From 11da068e9abbdd52e15c7894d3c127cec9e54ffe Mon Sep 17 00:00:00 2001 From: mack-a <57424792+mack-a@users.noreply.github.com> Date: Tue, 1 Sep 2026 00:21:40 +0800 Subject: [PATCH] sync: update English installer implementation --- shell/install_en.sh | 10092 +++++++++++++++++++++++++----------------- 1 file changed, 5958 insertions(+), 4134 deletions(-) mode change 100644 => 100755 shell/install_en.sh diff --git a/shell/install_en.sh b/shell/install_en.sh old mode 100644 new mode 100755 index d1d96f6..f954704 --- a/shell/install_en.sh +++ b/shell/install_en.sh @@ -1,4 +1,5 @@ #!/usr/bin/env bash +# ------------------------------------------------------------- # Detection area #------------------------------------------------ ---------- # Check system @@ -8,6 +9,7 @@ echoContent() { case $1 in # red "red") + # shellcheck disable=SC2154 # shellcheck disable=SC2154 ${echoType} "\033[31m${printN}$2 \033[0m" ;; @@ -34,10 +36,10 @@ echoContent() { } # Check SELinux status checkCentosSELinux() { - if [[ -f "/etc/selinux/config" ]] && ! grep -q "SELINUX=disabled" <"/etc/selinux/config"; then + if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" == "Enforcing" ]; 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 " + echoContent yellow "https://www.v2ray-agent.com/archives/1684115970026#centos-%E5%85%B3%E9%97%ADselinux" exit 0 fi } @@ -56,16 +58,22 @@ checkSystem() { release="centos" installType='yum -y install' removeType='yum -y remove' - upgrade="yum update -y --skip-broken" + # upgrade="yum update -y --skip-broken" checkCentosSELinux - elif [[ -f "/etc/issue" ]] && grep " @@ -113,7 +119,7 @@ checkCPUVendor() { else echoContent red "This CPU architecture cannot be recognized, the default is amd64, x86_64--->" xrayCoreCPUVendor="Xray-linux-64" - v2rayCoreCPUVendor="v2ray-linux-64" + # v2rayCoreCPUVendor="v2ray-linux-64" fi } @@ -123,20 +129,15 @@ initVar() { removeType='yum -y remove' upgrade="yum -y update" echoType='echo -e' + # sudoCMD="" #CPU version supported by the core xrayCoreCPUVendor="" - v2rayCoreCPUVendor="" - hysteriaCoreCPUVendor="" warpRegCoreCPUVendor="" cpuVendor="" # domain name domain= - - #Address of CDN node - add= - # Total installation progress totalProgress=1 @@ -145,11 +146,16 @@ initVar() { #3.v2ray-core[xtls] installation coreInstallType= + # coreInstallPath= + + # v2ctl Path # Core installation path # coreInstallPath= # v2ctl Path ctlPath= + # v2rayAgentInstallType= + #1.Install all #2.Personalized installation # v2rayAgentInstallType= @@ -172,16 +178,52 @@ initVar() { # xray-core reality state realityStatus= - # Path to hysteria configuration file - hysteriaConfigPath= + singBoxConfigPath= + + + singBoxVLESSVisionPort= + singBoxVLESSRealityVisionPort= + singBoxVLESSRealityGRPCPort= + singBoxHysteria2Port= + singBoxTrojanPort= + singBoxTuicPort= + singBoxNaivePort= + singBoxVMessWSPort= + singBoxVLESSWSPort= + singBoxVMessHTTPUpgradePort= + + subscribePort= + + subscribeType= + + # sing-box reality serverName publicKey + singBoxVLESSRealityGRPCServerName= + singBoxVLESSRealityVisionServerName= + singBoxVLESSRealityPublicKey= + + # xray-core reality serverName publicKey + xrayVLESSRealityServerName= + xrayVLESSRealityPort= + xrayVLESSRealityXHTTPServerName= + xrayVLESSRealityXHTTPort= + # xrayVLESSRealityPublicKey= + + # interfaceName= # interfaceName= # Port hopping portHoppingStart= portHoppingEnd= portHopping= - # tuic configuration file path - tuicConfigPath= + hysteria2PortHoppingStart= + hysteria2PortHoppingEnd= + hysteria2PortHopping= + + # tuicPortHoppingStart= + # tuicPortHoppingEnd= + # tuicPortHopping= + + # tuicConfigPath= tuicAlgorithm= tuicPort= @@ -194,23 +236,25 @@ initVar() { #The core type selected during installation selectCoreType= - #Default core version - v2rayCoreVersion= + # v2rayCoreVersion= # Random path customPath= + # centos version # centos version centosVersion= + # UUID #UUID currentUUID= + # clients #clients currentClients= # previousClients - previousClients= + # previousClients= localIP= @@ -220,6 +264,7 @@ initVar() { #Number of attempts after tls installation failure installTLSCount= + # BTPanelStatus= #BTPanel status # BTPanelStatus= # Pagoda domain name @@ -233,6 +278,8 @@ initVar() { # ssl type sslType= + # SSL CF API Token + cfAPIToken= #sslmail sslEmail= @@ -240,14 +287,14 @@ initVar() { # Check the number of days sslRenewalDays=90 - # dns ssl status - dnsSSLStatus= + # dnsSSLStatus= + # dns tls domain # dns tls domain dnsTLSDomain= + ipType= - # Whether the domain name installs a wildcard certificate through dns - installDNSACMEStatus= + # installDNSACMEStatus= # Custom port customPort= @@ -255,23 +302,25 @@ initVar() { #hysteriaport hysteriaPort= - #hysteriaprotocol - hysteriaProtocol= + # hysteriaProtocol= - #hysteriadelay - hysteriaLag= + # hysteriaLag= - # hysteriadownload speed - hysteriaClientDownloadSpeed= + hysteria2ClientDownloadSpeed= - # hysteria uplink speed - hysteriaClientUploadSpeed= + hysteria2ClientUploadSpeed= + # Reality #Reality realityPrivateKey= - realityServerNames= + realityServerName= realityDestDomain= + # isPortOpen= + # wildcardDomainStatus= + # nginxIPort= + + # wget show progress #Port status # isPortOpen= # Wildcard domain name status @@ -282,25 +331,37 @@ initVar() { # wget show progress wgetShowProgressStatus= + # warp #warp reservedWarpReg= publicKeyWarpReg= addressWarpReg= secretKeyWarpReg= + + lastInstallationConfig= + } # Read tls certificate details readAcmeTLS() { + local readAcmeDomain= if [[ -n "${currentHost}" ]]; then - dnsTLSDomain=$(echo "${currentHost}" | awk -F "[.]" '{print $(NF-1)"."$NF}') + readAcmeDomain="${currentHost}" fi + + if [[ -n "${domain}" ]]; then + readAcmeDomain="${domain}" + fi + + dnsTLSDomain=$(echo "${readAcmeDomain}" | awk -F "." '{$1="";print $0}' | sed 's/^[[:space:]]*//' | sed 's/ /./g') 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 + installedDNSAPIStatus=true fi } + # Read the default custom port readCustomPort() { - if [[ -n "${configPath}" && -z "${realityStatus}" ]]; then + if [[ -n "${configPath}" && -z "${realityStatus}" && "${coreInstallType}" == "1" ]]; then local port= port=$(jq -r .inbounds[0].port "${configPath}${frontingType}.json") if [[ "${port}" != "443" ]]; then @@ -308,49 +369,58 @@ readCustomPort() { fi fi } + +readNginxSubscribe() { + subscribeType="https" + if [[ -f "${nginxConfigPath}subscribe.conf" ]]; then + if grep -q "sing-box" "${nginxConfigPath}subscribe.conf"; then + subscribePort=$(grep "listen" "${nginxConfigPath}subscribe.conf" | awk '{print $2}') + subscribeDomain=$(grep "server_name" "${nginxConfigPath}subscribe.conf" | awk '{print $2}') + subscribeDomain=${subscribeDomain//;/} + if [[ -n "${currentHost}" && "${subscribeDomain}" != "${currentHost}" ]]; then + subscribePort= + subscribeType= + else + if ! grep "listen" "${nginxConfigPath}subscribe.conf" | grep -q "ssl"; then + subscribeType="http" + fi + fi + + fi + fi +} + # Detect installation method readInstallType() { coreInstallType= configPath= - hysteriaConfigPath= + singBoxConfigPath= #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" @@ -428,7 +640,10 @@ checkBTPanel() { ln -s "/www/server/panel/vhost/cert/${btDomain}/privkey.pem" "/etc/v2ray-agent/tls/${btDomain}.key" fi - nginxStaticPath="/www/wwwroot/${btDomain}/" + nginxStaticPath="/www/wwwroot/${btDomain}/html/" + + mkdir -p "/www/wwwroot/${btDomain}/html/" + if [[ -f "/www/wwwroot/${btDomain}/.user.ini" ]]; then chattr -i "/www/wwwroot/${btDomain}/.user.ini" fi @@ -441,13 +656,38 @@ checkBTPanel() { fi fi } -# Read the current alpn order -readInstallAlpn() { - 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} +check1Panel() { + if [[ -n $(pgrep -f "1panel") ]]; then + if [[ -d '/opt/1panel/apps/openresty/openresty/www/sites/' && -n $(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem) ]]; then + if [[ -z "${currentHost}" ]]; then + echoContent skyBlue "\nProgress$1/${totalProgress}: Installation tools" + + find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}' + + read -r -p "Enter the number:" selectBTDomain + else + selectBTDomain=$(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}' | grep "${currentHost}" | cut -d ":" -f 1) + fi + + if [[ -n "${selectBTDomain}" ]]; then + btDomain=$(find /opt/1panel/apps/openresty/openresty/www/sites/*/ssl/fullchain.pem | awk -F "[/]" '{print $9}' | awk '{print NR""":"$0}' | grep "${selectBTDomain}:" | cut -d ":" -f 2) + + if [[ -z "${btDomain}" ]]; then + echoContent red " ---> $1 port opening failed" + check1Panel + else + domain=${btDomain} + if [[ ! -f "/etc/v2ray-agent/tls/${btDomain}.crt" && ! -f "/etc/v2ray-agent/tls/${btDomain}.key" ]]; then + ln -s "/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/ssl/fullchain.pem" "/etc/v2ray-agent/tls/${btDomain}.crt" + ln -s "/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/ssl/privkey.pem" "/etc/v2ray-agent/tls/${btDomain}.key" + fi + + nginxStaticPath="/opt/1panel/apps/openresty/openresty/www/sites/${btDomain}/index/" + fi + else + echoContent red " ---> $1 port opening failed" + check1Panel + fi fi fi } @@ -458,35 +698,21 @@ allowPort() { 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 command -v dpkg >/dev/null 2>&1 && dpkg -l | grep -q "^[[:space:]]*ii[[:space:]]\+ufw"; 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/${type}"; then updateFirewalldStatus=true local firewallPort=$1 - - if echo "${firewallPort}" | grep ":"; then - firewallPort=$(echo "${firewallPort}" | awk -F ":" '{print $1-$2}') + if echo "${firewallPort}" | grep -q ":"; then + firewallPort=$(echo "${firewallPort}" | awk -F ":" '{print $1"-"$2}') fi - firewall-cmd --zone=public --add-port="${firewallPort}/${type}" --permanent checkFirewalldAllowPort "${firewallPort}" fi @@ -494,6 +720,23 @@ allowPort() { if echo "${updateFirewalldStatus}" | grep -q "true"; then firewall-cmd --reload fi + elif rc-update show 2>/dev/null | grep -q ufw; 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 dpkg -l | grep -q "^[[:space:]]*ii[[:space:]]\+netfilter-persistent" && 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 fi } # Get public IP @@ -502,7 +745,7 @@ getPublicIP() { if [[ -n "$1" ]]; then type=$1 fi - if [[ -n "${currentHost}" && -n "${currentRealityServerNames}" && "${currentRealityServerNames}" == "${currentHost}" && -z "$1" ]]; then + if [[ -n "${currentHost}" && -z "$1" ]] && [[ "${singBoxVLESSRealityVisionServerName}" == "${currentHost}" || "${singBoxVLESSRealityGRPCServerName}" == "${currentHost}" || "${xrayVLESSRealityServerName}" == "${currentHost}" ]]; then echo "${currentHost}" else local currentIP= @@ -520,7 +763,7 @@ checkUFWAllowPort() { if ufw status | grep -q "$1"; then echoContent green " ---> $1 port opened successfully" else - echoContent red " ---> $1 port opening failed" + echoContent red "acme installation failed--->" exit 0 fi } @@ -530,40 +773,62 @@ checkFirewalldAllowPort() { if firewall-cmd --list-ports --permanent | grep -q "$1"; then echoContent green " ---> $1 port opened successfully" else - echoContent red " ---> $1 port opening failed" + 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/]" exit 0 fi } -# 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 -} -# 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= +readSingBoxConfig() { + tuicPort= + hysteriaPort= + if [[ -n "${singBoxConfigPath}" ]]; then - 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") + if [[ -f "${singBoxConfigPath}09_tuic_inbounds.json" ]]; then + tuicPort=$(jq -r '.inbounds[0].listen_port' "${singBoxConfigPath}09_tuic_inbounds.json") + tuicAlgorithm=$(jq -r '.inbounds[0].congestion_control' "${singBoxConfigPath}09_tuic_inbounds.json") + fi + if [[ -f "${singBoxConfigPath}06_hysteria2_inbounds.json" ]]; then + hysteriaPort=$(jq -r '.inbounds[0].listen_port' "${singBoxConfigPath}06_hysteria2_inbounds.json") + hysteria2ClientUploadSpeed=$(jq -r '.inbounds[0].down_mbps' "${singBoxConfigPath}06_hysteria2_inbounds.json") + hysteria2ClientDownloadSpeed=$(jq -r '.inbounds[0].up_mbps' "${singBoxConfigPath}06_hysteria2_inbounds.json") + fi + fi +} + +readLastInstallationConfig() { + if [[ -n "${configPath}" ]]; then + read -r -p "Previous installation configuration found. Use it? [y/n]:" lastInstallationConfigStatus + if [[ "${lastInstallationConfigStatus}" == "y" ]]; then + lastInstallationConfig=true + fi + fi +} +unInstallSingBox() { + local type=$1 + if [[ -n "${singBoxConfigPath}" ]]; then + if grep -q 'tuic' 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]" + fi + + if grep -q 'hysteria2' Install wget" + fi + rm "${singBoxConfigPath}config.json" + fi + + readInstallType + + if [[ -n "${singBoxConfigPath}" ]]; then + echoContent yellow "https://www.v2ray-agent.com/archives/1679931532764#heading-8 " + handleSingBox stop + handleSingBox start + else + handleSingBox stop + rm /etc/systemd/system/sing-box.service + rm -rf /etc/v2ray-agent/sing-box/* + echoContent green " ---> Install curl" fi } @@ -575,18 +840,17 @@ readConfigHostPathUUID() { currentClients= currentHost= currentPort= - currentAdd= + currentCDNAddress= + singBoxVMessWSPath= + singBoxVLESSWSPath= + singBoxVMessHTTPUpgradePath= if [[ "${coreInstallType}" == "1" ]]; then # 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 [[ "${currentAdd}" == "null" ]]; then - currentAdd=${currentHost} - fi currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) local defaultPortFile= @@ -602,49 +866,90 @@ readConfigHostPathUUID() { 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) + if echo ${currentInstallProtocolType} | grep -q ",7,"; then + currentClients=$(jq -r .inbounds[1].settings.clients ${configPath}07_VLESS_vision_reality_inbounds.json) + currentUUID=$(jq -r .inbounds[1].settings.clients[0].id ${configPath}07_VLESS_vision_reality_inbounds.json) + xrayVLESSRealityVisionPort=$(jq -r .inbounds[0].port ${configPath}07_VLESS_vision_reality_inbounds.json) + if [[ "${currentPort}" == "${xrayVLESSRealityVisionPort}" ]]; then + xrayVLESSRealityVisionPort="${currentDefaultPort}" + fi + fi + # reality xhttp + if echo ${currentInstallProtocolType} | grep -q ",12,"; then + + currentClients=$(jq -r .inbounds[0].settings.clients ${configPath}12_VLESS_XHTTP_inbounds.json) + currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}12_VLESS_XHTTP_inbounds.json) + xrayVLESSRealityXHTTPort=$(jq -r .inbounds[0].port ${configPath}12_VLESS_XHTTP_inbounds.json) + if [[ "${currentPort}" == "${xrayVLESSRealityXHTTPort}" ]]; then + xrayVLESSRealityXHTTPort="${currentDefaultPort}" + fi + currentPath=$(jq -r .inbounds[0].streamSettings.xhttpSettings.path ${configPath}12_VLESS_XHTTP_inbounds.json | awk -F "[/]" '{print $2}' | awk -F "[x][H][T][T][P]" '{print $1}') 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) - - if [[ "${currentAdd}" == "null" ]]; then - currentAdd=${currentHost} + if [[ -n "${frontingType}" ]]; then + currentHost=$(jq -r .inbounds[0].tls.server_name ${configPath}${frontingType}.json) + if echo ${currentInstallProtocolType} | grep -q ",11," && [[ "${currentHost}" == "null" ]]; then + currentHost=$(grep 'server_name' <${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf | awk '{print $2}') + currentHost=${currentHost//;/} + fi + currentUUID=$(jq -r .inbounds[0].users[0].uuid ${configPath}${frontingType}.json) + currentClients=$(jq -r .inbounds[0].users ${configPath}${frontingType}.json) + else + currentUUID=$(jq -r .inbounds[0].users[0].uuid ${configPath}${frontingTypeReality}.json) + currentClients=$(jq -r .inbounds[0].users ${configPath}${frontingTypeReality}.json) fi - currentUUID=$(jq -r .inbounds[0].settings.clients[0].id ${configPath}${frontingType}.json) - currentPort=$(jq .inbounds[0].port ${configPath}${frontingType}.json) fi #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 [[ "${coreInstallType}" == "1" ]]; then + local fallback + fallback=$(jq -r -c '.inbounds[0].settings.fallbacks[]|select(.path)' ${configPath}${frontingType}.json | head -1) - local path - path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}') + local path + path=$(echo "${fallback}" | jq -r .path | awk -F "[/]" '{print $2}') - if [[ $(echo "${fallback}" | jq -r .dest) == 31297 ]]; then - 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 + 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}') + 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 + # check1Panel + 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 + if [[ -z "${currentPath}" && -f "${configPath}12_VLESS_XHTTP_inbounds.json" ]]; then + currentPath=$(jq -r .inbounds[0].streamSettings.xhttpSettings.path "${configPath}12_VLESS_XHTTP_inbounds.json" | awk -F "[x][H][T][T][P]" '{print $1}' | awk -F "[/]" '{print $2}') + fi + elif [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}05_VMess_WS_inbounds.json" ]]; then + singBoxVMessWSPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}05_VMess_WS_inbounds.json") + currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}05_VMess_WS_inbounds.json" | awk -F "[/]" '{print $2}') fi - + if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}03_VLESS_WS_inbounds.json" ]]; then + singBoxVLESSWSPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}03_VLESS_WS_inbounds.json") + currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}03_VLESS_WS_inbounds.json" | awk -F "[/]" '{print $2}') + currentPath=${currentPath::-2} + fi + if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json" ]]; then + singBoxVMessHTTPUpgradePath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json") + currentPath=$(jq -r .inbounds[0].transport.path "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json" | awk -F "[/]" '{print $2}') + fi + fi + if [[ -f "/etc/v2ray-agent/cdn" ]] && [[ -n "$(head -1 /etc/v2ray-agent/cdn)" ]]; then + currentCDNAddress=$(head -1 /etc/v2ray-agent/cdn) + else + currentCDNAddress="${currentHost}" fi } @@ -653,93 +958,96 @@ showInstallStatus() { if [[ -n "${coreInstallType}" ]]; then if [[ "${coreInstallType}" == 1 ]]; then if [[ -n $(pgrep -f "xray/xray") ]]; then + echoContent yellow "$(cat /etc/issue)" + else + echoContent yellow "$(cat /proc/version)" + fi + + elif [[ "${coreInstallType}" == 2 ]]; then + if [[ -n $(pgrep -f "sing-box/sing-box") ]]; 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 if [[ -n ${currentInstallProtocolType} ]]; then - echoContent yellow "Installed protocol: \c" + echoContent yellow "\nCore: v2ray-core[Running]" 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 + if echo ${currentInstallProtocolType} | grep -q ",0,"; then + echoContent yellow "VLESS+TCP[TLS_Vision] \c" 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 + if echo ${currentInstallProtocolType} | grep -q ",1,"; then echoContent yellow "VLESS+WS[TLS] \c" fi - if echo ${currentInstallProtocolType} | grep -q 2; then + if echo ${currentInstallProtocolType} | grep -q ",2,"; then echoContent yellow "Trojan+gRPC[TLS] \c" fi - if echo ${currentInstallProtocolType} | grep -q 3; then + if echo ${currentInstallProtocolType} | grep -q ",3,"; then echoContent yellow "VMess+WS[TLS] \c" fi - if echo ${currentInstallProtocolType} | grep -q 4; then + if echo ${currentInstallProtocolType} | grep -q ",4,"; then echoContent yellow "Trojan+TCP[TLS] \c" fi - if echo ${currentInstallProtocolType} | grep -q 5; then + if echo ${currentInstallProtocolType} | grep -q ",5,"; then echoContent yellow "VLESS+gRPC[TLS] \c" fi - if echo ${currentInstallProtocolType} | grep -q 7; then + if echo ${currentInstallProtocolType} | grep -q ",6,"; then + echoContent yellow "Hysteria2 \c" + fi + if echo ${currentInstallProtocolType} | grep -q ",7,"; then echoContent yellow "VLESS+Reality+Vision \c" fi - if echo ${currentInstallProtocolType} | grep -q 8; then + if echo ${currentInstallProtocolType} | grep -q ",8,"; then echoContent yellow "VLESS+Reality+gRPC \c" fi + if echo ${currentInstallProtocolType} | grep -q ",9,"; then + echoContent yellow "Tuic \c" + fi + if echo ${currentInstallProtocolType} | grep -q ",10,"; then + echoContent yellow "Naive \c" + fi + if echo ${currentInstallProtocolType} | grep -q ",11,"; then + echoContent yellow "VMess+TLS+HTTPUpgrade \c" + fi + if echo ${currentInstallProtocolType} | grep -q ",12,"; then + echoContent yellow "VLESS+Reality+XHTTP \c" + fi + if echo ${currentInstallProtocolType} | grep -q ",13,"; then + echoContent yellow "AnyTLS \c" + fi fi } # 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 - - elif [[ "$1" == "v2rayDel" ]]; then - rm -rf /etc/v2ray-agent/v2ray/* - - elif [[ "$1" == "xrayDel" ]]; then + if [[ "$1" == "xrayDel" ]]; then + handleXray stop rm -rf /etc/v2ray-agent/xray/* + elif [[ "$1" == "singBoxDel" ]]; then + handleSingBox stop + rm -rf /etc/v2ray-agent/sing-box/conf/config.json >/dev/null 2>&1 + rm -rf /etc/v2ray-agent/sing-box/conf/config/* >/dev/null 2>&1 fi } initVar "$1" checkSystem checkCPUVendor + readInstallType readInstallProtocolType readConfigHostPathUUID -readInstallAlpn readCustomPort -readXrayCoreRealityConfig +readSingBoxConfig +# ------------------------------------------------------------- + #------------------------------------------------ ---------- #Initialize the installation directory @@ -755,22 +1063,31 @@ mkdirTools() { 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/subscribe/sing-box + mkdir -p /etc/v2ray-agent/subscribe/sing-box_profiles + mkdir -p /etc/v2ray-agent/subscribe_local/sing-box + mkdir -p /etc/v2ray-agent/xray/conf + mkdir -p /etc/v2ray-agent/xray/reality_scan 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 -} + mkdir -p /etc/v2ray-agent/sing-box/conf/config + mkdir -p /usr/share/nginx/html/ +} +checkRoot() { + if [ "$(id -u)" -ne 0 ]; then + # sudoCMD="sudo" + echo "${currentHost}" + fi +} # Install toolkit installTools() { - echoContent skyBlue "\nProgress$1/${totalProgress}: Installation tools" + echoContent skyBlue "sed -i \"1i\\\nameserver 2001:67c:2b0::4\\\nnameserver 2a00:1098:2c::1\" /etc/resolv.conf" # Repair individual system problems in ubuntu if [[ "${release}" == "ubuntu" ]]; then dpkg --configure -a @@ -780,9 +1097,12 @@ installTools() { 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 then execute it again]" + echoContent green " ---> install unzip" + + if [[ "${release}" != "centos" ]]; then + ${upgrade} >/etc/v2ray-agent/install.log 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 @@ -792,91 +1112,108 @@ installTools() { ${installType} epel-release >/dev/null 2>&1 fi - # [[ -z `find /usr/bin /usr/sbin |grep -v grep|grep -w curl` ]] + if ! sudo --version >/dev/null 2>&1; then + echoContent green " ---> Install socat" + ${installType} sudo >/dev/null 2>&1 + fi - if ! find /usr/bin /usr/sbin | grep -q -w wget; then - echoContent green " ---> Install wget" + if ! wget --help >/dev/null 2>&1; then + echoContent green " ---> Install tar" ${installType} wget >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w curl; then - echoContent green " ---> Install curl" + # if ! command -v netfilter-persistent >/dev/null 2>&1; then + # if [[ "${release}" != "centos" ]]; then + # echo "iptables-persistent iptables-persistent/autosave_v4 boolean true" | sudo debconf-set-selections + # echo "iptables-persistent iptables-persistent/autosave_v6 boolean true" | sudo debconf-set-selections + # ${installType} iptables-persistent >/dev/null 2>&1 + # fi + # fi + + if ! curl --help >/dev/null 2>&1; then + echoContent green " ---> install crontabs" ${installType} curl >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w unzip; then - echoContent green " ---> install unzip" + if ! unzip >/dev/null 2>&1; then + echoContent green " ---> Install jq" ${installType} unzip >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w socat; then - echoContent green " ---> Install socat" + if ! socat -h >/dev/null 2>&1; then + echoContent green " ---> Install binutils" ${installType} socat >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w tar; then - echoContent green " ---> Install tar" + if ! tar --help >/dev/null 2>&1; then + echoContent green " ---> Install ping6" ${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 + if ! crontab -l >/dev/null 2>&1; then + echoContent green " ---> Install qrencode" + 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" + if ! jq --help >/dev/null 2>&1; then + echoContent green " ---> install sudo" ${installType} jq >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w binutils; then - echoContent green " ---> Install binutils" + if ! command -v ld >/dev/null 2>&1; then + echoContent green " ---> install lsb-release" ${installType} binutils >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w ping6; then - echoContent green " ---> Install ping6" + if ! openssl help >/dev/null 2>&1; then + echoContent green " ---> Install lsof" + ${installType} openssl >/dev/null 2>&1 + fi + + if ! ping6 --help >/dev/null 2>&1; then + echoContent green " ---> Install dig" ${installType} inetutils-ping >/dev/null 2>&1 fi - if ! find /usr/bin /usr/sbin | grep -q -w qrencode; then - echoContent green " ---> Install qrencode" + if ! qrencode --help >/dev/null 2>&1; then + echoContent green " ---> Detected services that do not depend on Nginx, skip installation" ${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 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 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 + if ! command -v lsb_release >/dev/null 2>&1; then + if [[ "${release}" == "ubuntu" || "${release}" == "debian" ]]; then + ${installType} lsb-release >/dev/null 2>&1 + elif [[ "${release}" == "centos" ]]; then + ${installType} redhat-lsb-core >/dev/null 2>&1 + else + ${installType} lsb-release >/dev/null 2>&1 fi fi - # 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 + if ! lsof -h >/dev/null 2>&1; then echoContent green " ---> Install nginx" + ${installType} lsof >/dev/null 2>&1 + fi + + if ! dig -h >/dev/null 2>&1; then + echoContent green " ---> Install nginx" + if echo "${installType}" | grep -qw "apt"; then + ${installType} dnsutils >/dev/null 2>&1 + elif echo "${installType}" | grep -qw "yum"; then + ${installType} bind-utils >/dev/null 2>&1 + elif echo "${installType}" | grep -qw "apk"; then + ${installType} bind-tools >/dev/null 2>&1 + fi + fi + + if echo "${selectCustomInstallType}" | grep -qwE ",7,|,8,|,7,8,|,12,|,7,12,"; then + echoContent green " ---> Install semanage" + else + if ! nginx >/dev/null 2>&1; then + echoContent green " ---> Detected services that do not depend on certificates, skip installation" installNginxTools else nginxVersion=$(nginx -v 2>&1) @@ -885,8 +1222,8 @@ installTools() { 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" + echoContent yellow "\nCore: v2ray-core[not running]" + echoContent green " ---> Install acme.sh" installNginxTools >/dev/null 2>&1 else exit 0 @@ -895,47 +1232,55 @@ installTools() { 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 ! command -v semanage >/dev/null 2>&1 && [[ "${release}" == "centos" ]]; then + # if command -v getenforce >/dev/null 2>&1 && [ "$(getenforce)" == "Enforcing" ]; then + # if [[ "${centosVersion}" == "7" ]]; then + # policyCoreUtils="policycoreutils-python" + # elif [[ "${centosVersion}" == "8" || "${centosVersion}" == "9" || "${centosVersion}" == "10" ]]; then + # policyCoreUtils="policycoreutils-python-utils" + # fi + # + # if [[ -n "${policyCoreUtils}" ]]; then + # ${installType} bash-completion >/dev/null 2>&1 + # ${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 - 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 - - fi - fi + # Detect nginx version and provide the option of uninstalling it if [[ "${selectCustomInstallType}" == "7" ]]; then - echoContent green " ---> Detected services that do not depend on certificates, skip installation" + echoContent green " ---> Install WARP" else if [[ ! -d "$HOME/.acme.sh" ]] || [[ -d "$HOME/.acme.sh" && -z $(find "$HOME/.acme.sh/acme.sh") ]]; then - echoContent green " ---> Install acme.sh" + echoContent green " ---> WARP started successfully" 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" + tail -n 100 /etc/v2ray-agent/tls/acme.log + echoContent yellow "Installed protocol: \c" 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" + echoContent red " ---> The official WARP client does not support ARM architecture" + echoContent red " ---> Failed to install WARP" + echoContent skyBlue " sed -i \"1i\\\nameserver 2a00:1098:2b::1\\\nnameserver 2a00:1098:2c::1\\\nnameserver 2a01:4f8:c2c:123f::1\\\nnameserver 2a01:4f9:c010:3f02::1\" /etc/resolv.conf" exit 0 fi fi fi } - +bootStartup() { + local serviceName=$1 + if [[ "${release}" == "alpine" ]]; then + rc-update add "${serviceName}" default + else + systemctl daemon-reload + systemctl enable "${serviceName}" + fi +} # Install Nginx installNginxTools() { @@ -945,6 +1290,7 @@ installNginxTools() { 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 + # 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 @@ -954,6 +1300,7 @@ installNginxTools() { 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 + # 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 @@ -977,16 +1324,17 @@ gpgkey=https://nginx.org/keys/nginx_signing.key module_hotfixes=true EOF sudo yum-config-manager --enable nginx-mainline >/dev/null 2>&1 + elif [[ "${release}" == "alpine" ]]; then + rm "${nginxConfigPath}default.conf" fi ${installType} nginx >/dev/null 2>&1 - systemctl daemon-reload - systemctl enable nginx + bootStartup nginx } # Install warp installWarp() { if [[ "${cpuVendor}" == "arm" ]]; then - echoContent red " ---> The official WARP client does not support ARM architecture" + echoContent red " ---> Unable to obtain domain name IPv4 address through DNS" exit 0 fi @@ -1006,10 +1354,10 @@ installWarp() { sudo rpm -ivh "http://pkg.cloudflareclient.com/cloudflare-release-el${centosVersion}.rpm" >/dev/null 2>&1 fi - echoContent green " ---> Install WARP" + echoContent green " ---> Try to check the domain name IPv6 address" ${installType} cloudflare-warp >/dev/null 2>&1 if [[ -z $(which warp-cli) ]]; then - echoContent red " ---> Failed to install WARP" + echoContent red " ---> Unable to obtain domain name IPv6 address through DNS, exit installation" exit 0 fi systemctl enable warp-svc @@ -1023,7 +1371,7 @@ installWarp() { 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" + echoContent green " ---> Current VPS IP: ${publicIP}" fi } @@ -1031,155 +1379,142 @@ installWarp() { checkDNSIP() { local domain=$1 local dnsIP= - local type=4 - dnsIP=$(dig @1.1.1.1 +time=1 +short "${domain}") + ipType=4 + dnsIP=$(dig @1.1.1.1 +time=2 +short "${domain}" | grep -E "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$") if [[ -z "${dnsIP}" ]]; then - dnsIP=$(dig @8.8.8.8 +time=1 +short "${domain}") + dnsIP=$(dig @8.8.8.8 +time=2 +short "${domain}" | grep -E "^(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$") 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 + echoContent red " ---> The domain name resolution IP is inconsistent with the current server IP\n" + echoContent green " ---> DNS resolution IP: ${dnsIP}" + dnsIP=$(dig @2606:4700:4700::1111 +time=2 aaaa +short "${domain}") + ipType=6 if echo "${dnsIP}" | grep -q "network unreachable" || [[ -z "${dnsIP}" ]]; then - echoContent red " ---> Unable to obtain domain name IPv6 address through DNS, exit installation" + echoContent red " ---> Please check if there is a web firewall, such as Oracle and other cloud service providers" exit 0 fi fi local publicIP= - publicIP=$(getPublicIP "${type}") + publicIP=$(getPublicIP "${ipType}") 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}" + echoContent red " ---> Check whether you have installed nginx and there are configuration conflicts. You can try DD pure system and try again" + echoContent yellow "VLESS+TCP[TLS] \c" + echoContent green " ---> Domain name IP verification passed" + echoContent green " ---> Detected that ${port} port is open" exit 0 else - echoContent green " ---> Domain name IP verification passed" + echoContent green " ---> No open ${port} port detected, exit installation" fi } # Check the actual open status of the port checkPortOpen() { + handleSingBox stop >/dev/null 2>&1 + handleXray stop >/dev/null 2>&1 local port=$1 local domain=$2 local checkPortOpenResult= - + # open port 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 + if [[ -z "${btDomain}" ]]; then - # 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 + # Change setting + handleNginx stop + #Initialize nginx configuration + touch ${nginxConfigPath}checkPortOpen.conf + local listenIPv6PortConfig= + + if [[ -n $(curl -s -6 -m 4 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) ]]; then + listenIPv6PortConfig="listen [::]:${port};" fi - exit 0 + cat <${nginxConfigPath}checkPortOpen.conf +server { + listen ${port}; + ${listenIPv6PortConfig} + 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 + checkPortOpenResult=$(curl -s -m 10 "http://${domain}:${port}/checkPort") + localIP=$(curl -s -m 10 "http://${domain}:${port}/ip") + rm "${nginxConfigPath}checkPortOpen.conf" + handleNginx stop + if [[ "${checkPortOpenResult}" == "fjkvymb6len" ]]; then + echoContent green " ---> Delete Nginx default configuration" + else + echoContent green " ---> Check that the current domain name IP is correct" + if echo "${checkPortOpenResult}" | grep -q "cloudflare"; then + echoContent yellow "VLESS+TCP[TLS_Vision] \c" + else + if [[ -z "${checkPortOpenResult}" ]]; then + echoContent red " ---> Error log: ${checkPortOpenResult}, please submit feedback on this error log through issues" + echoContent red "Domain name cannot be empty--->" + else + echoContent red "\n ---> The ip of the current domain name was not detected" + fi + fi + exit 0 + fi + checkIP "${localIP}" fi - checkIP "${localIP}" } # Initialize Nginx application certificate configuration initTLSNginxConfig() { handleNginx stop echoContent skyBlue "\nProgress $1/${totalProgress}: Initializing Nginx application certificate configuration" - if [[ -n "${currentHost}" ]]; then + if [[ -n "${currentHost}" && -z "${lastInstallationConfig}" ]]; 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}" + echoContent yellow "Trojan+TCP[TLS_Vision] \c" else echo - echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" + echoContent yellow "VLESS+WS[TLS] \c" read -r -p "domain name:" domain fi + elif [[ -n "${currentHost}" && -n "${lastInstallationConfig}" ]]; then + domain=${currentHost} else echo - echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" + echoContent yellow "Trojan+gRPC[TLS] \c" read -r -p "domain name:" domain fi if [[ -z ${domain} ]]; then - echoContent red "Domain name cannot be empty--->" + echoContent red " ---> Exception result: ${localIP}" + # Apply for tls initTLSNginxConfig 3 else - dnsTLSDomain=$(echo "${domain}" | awk -F "[.]" '{print $(NF-1)"."$NF}') - customPortFunction - # Change setting + dnsTLSDomain=$(echo "${domain}" | awk -F "." '{$1="";print $0}' | sed 's/^[[:space:]]*//' | sed 's/ /./g') + if [[ "${selectCoreType}" == "1" ]]; then + customPortFunction + fi 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 - - # readAcmeTLS - # handleNginx start } # 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 + echoContent green " ---> Added successfully" + rm -rf ${nginxConfigPath}default.conf >/dev/null 2>&1 fi fi } @@ -1188,36 +1523,36 @@ updateRedirectNginxConf() { local redirectDomain= redirectDomain=${domain}:${port} + local nginxH2Conf= + nginxH2Conf="listen 127.0.0.1:31302 http2 so_keepalive=on proxy_protocol;" + nginxVersion=$(nginx -v 2>&1) + + if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then + nginxH2Conf="listen 127.0.0.1:31302 so_keepalive=on proxy_protocol;http2 on;" + fi + cat <${nginxConfigPath}alone.conf -server { + server { 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 - local nginxH2Conf= - nginxH2Conf="listen 127.0.0.1:31302 http2 so_keepalive=on;" - nginxVersion=$(nginx -v 2>&1) + if echo "${selectCustomInstallType}" | grep -qE ",2,|,5," || [[ -z "${selectCustomInstallType}" ]]; then - 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 { ${nginxH2Conf} server_name ${domain}; root ${nginxStaticPath}; + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + client_header_timeout 1071906480m; keepalive_timeout 1071906480m; - location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { - default_type 'text/plain; charset=utf-8'; - alias /etc/v2ray-agent/subscribe/\$1/\$2; - } - location /${currentPath}grpc { if (\$content_type !~ "application/grpc") { return 404; @@ -1240,20 +1575,20 @@ server { grpc_pass grpc://127.0.0.1:31304; } location / { - add_header Strict-Transport-Security "max-age=15552000; preload" always; } } EOF - elif echo "${selectCustomInstallType}" | grep -q 5 || [[ -z "${selectCustomInstallType}" ]]; then + elif echo "${selectCustomInstallType}" | grep -q ",5," || [[ -z "${selectCustomInstallType}" ]]; then cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31302 http2; + ${nginxH2Conf} + + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + server_name ${domain}; 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; @@ -1265,23 +1600,26 @@ server { grpc_send_timeout 1071906480m; grpc_pass grpc://127.0.0.1:31301; } + location / { + } } EOF - elif echo "${selectCustomInstallType}" | grep -q 2 || [[ -z "${selectCustomInstallType}" ]]; then - + elif echo "${selectCustomInstallType}" | grep -q ",2," || [[ -z "${selectCustomInstallType}" ]]; then cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31302 http2; - server_name ${domain}; + ${nginxH2Conf} + + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + + server_name ${domain}; 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; # keepalive_time 1071906480m; + # keepalive_time 1071906480m; keepalive_requests 4294967296; client_body_timeout 1071906480m; send_timeout 1071906480m; @@ -1290,20 +1628,22 @@ server { grpc_send_timeout 1071906480m; grpc_pass grpc://127.0.0.1:31301; } + location / { + } } EOF else cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31302 http2; + ${nginxH2Conf} + + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + server_name ${domain}; root ${nginxStaticPath}; - location ~ ^/s/(clashMeta|default|clashMetaProfiles)/(.*) { - default_type 'text/plain; charset=utf-8'; - alias /etc/v2ray-agent/subscribe/\$1/\$2; - } location / { } } @@ -1312,20 +1652,70 @@ EOF cat <>${nginxConfigPath}alone.conf server { - listen 127.0.0.1:31300; + listen 127.0.0.1:31300 proxy_protocol; server_name ${domain}; + + set_real_ip_from 127.0.0.1; + real_ip_header proxy_protocol; + 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 } +# singbox Nginx config +singBoxNginxConfig() { + local type=$1 + local port=$2 + + local nginxH2Conf= + nginxH2Conf="listen ${port} http2 so_keepalive=on ssl;" + nginxVersion=$(nginx -v 2>&1) + + local singBoxNginxSSL= + singBoxNginxSSL="ssl_certificate /etc/v2ray-agent/tls/${domain}.crt;ssl_certificate_key /etc/v2ray-agent/tls/${domain}.key;" + + if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then + nginxH2Conf="listen ${port} so_keepalive=on ssl;http2 on;" + fi + + if echo "${selectCustomInstallType}" | grep -q ",11," || [[ "$1" == "all" ]]; then + cat <>${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf +server { + ${nginxH2Conf} + + server_name ${domain}; + root ${nginxStaticPath}; + ${singBoxNginxSSL} + + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305; + ssl_prefer_server_ciphers on; + + resolver 1.1.1.1 valid=60s; + resolver_timeout 2s; + client_max_body_size 100m; + + location /${currentPath} { + if (\$http_upgrade != "websocket") { + return 444; + } + + proxy_pass http://127.0.0.1:31306; + proxy_http_version 1.1; + proxy_set_header Upgrade \$http_upgrade; + proxy_set_header Connection "upgrade"; + proxy_set_header X-Real-IP \$remote_addr; + proxy_set_header X-Forwarded-For \$proxy_add_x_forwarded_for; + proxy_set_header Host \$host; + proxy_redirect off; + } +} +EOF + fi +} # check ip checkIP() { @@ -1333,29 +1723,28 @@ checkIP() { local localIP=$1 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 red "\n ---> Multiple IPs were detected, please confirm whether to turn off cloudflare" 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" + echoContent yellow "VMess+WS[TLS] \c" + echoContent yellow "Trojan+TCP[TLS] \c" + echoContent yellow "VLESS+gRPC[TLS] \c" + echoContent yellow "VLESS+Reality+Vision \c" 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}" + echoContent yellow "VLESS+Reality+gRPC \c" + echoContent red "\n==============================================================" 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}]" + if echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q "." || echo "${localIP}" | awk -F "[,]" '{print $2}' | grep -q ":"; then + echoContent red "================================================== ===============" + echoContent yellow " ---> nginx uninstall completed" + echoContent yellow "Error troubleshooting:" exit 0 fi - # echoContent green " ---> The current domain name ip is: [${localIP}]" - echoContent green " ---> Check that the current domain name IP is correct" + echoContent green " ---> Please add DNS TXT record manually" fi } # Custom email @@ -1374,23 +1763,76 @@ customSSLEmail() { 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" + echoContent green " ---> name: _acme-challenge" else - echoContent yellow "Please re-enter the correct email format [Example: username@example.com]" + echoContent yellow " ---> Please check whether the domain name resolution is valid and correct" customSSLEmail fi fi fi } +switchDNSAPI() { + read -r -p "Use DNS API to issue the certificate [NAT supported]? [y/n]:" dnsAPIStatus + if [[ "${dnsAPIStatus}" == "y" ]]; then + echoContent red "\n==============================================================" + echoContent yellow " ---> Please close the cloud and wait three minutes to try again" + echoContent yellow "2.aliyun" + echoContent red "==============================================================" + read -r -p "Select [Enter for default]:" selectDNSAPIType + case ${selectDNSAPIType} in + 1) + dnsAPIType="cloudflare" + ;; + 2) + dnsAPIType="aliyun" + ;; + *) + dnsAPIType="cloudflare" + ;; + esac + initDNSAPIConfig "${dnsAPIType}" + fi +} +initDNSAPIConfig() { + if [[ "$1" == "cloudflare" ]]; then + echoContent yellow "\n ---> Domain name: ${domain}" + read -r -p "Enter API Token:" cfAPIToken + if [[ -z "${cfAPIToken}" ]]; then + echoContent red " ---> buypass does not support free wildcard certificates" + initDNSAPIConfig "$1" + else + echo + if ! echo "${dnsTLSDomain}" | grep -q "\." || [[ -z $(echo "${dnsTLSDomain}" | awk -F "[.]" '{print $1}') ]]; then + echoContent green " ---> value: ${txtValue}" + exit 0 + fi + read -r -p "Use *.${dnsTLSDomain} to request a wildcard certificate via API? [y/n]:" dnsAPIStatus + fi + elif [[ "$1" == "aliyun" ]]; then + read -r -p "Enter Ali Key:" aliKey + read -r -p "Enter Ali Secret:" aliSecret + if [[ -z "${aliKey}" || -z "${aliSecret}" ]]; then + echoContent red " ---> Verification failed, please wait 1-2 minutes and try again" + initDNSAPIConfig "$1" + else + echo + if ! echo "${dnsTLSDomain}" | grep -q "\." || [[ -z $(echo "${dnsTLSDomain}" | awk -F "[.]" '{print $1}') ]]; then + echoContent green " ---> TXT record verification passed" + exit 0 + fi + read -r -p "Use *.${dnsTLSDomain} to request a wildcard certificate via API? [y/n]:" dnsAPIStatus + fi + fi +} #Select ssl installation type switchSSLType() { if [[ -z "${sslType}" ]]; then echoContent red "\n==============================================================" - echoContent yellow "1.letsencrypt[default]" + echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" echoContent yellow "2.zerossl" - echoContent yellow "3.buypass[Does not support DNS application]" - echoContent red "================================================== ===============" + echoContent yellow "Please enter the domain name to be configured: www.v2ray-agent.com --->" + echoContent red "==============================================================" read -r -p "Please select [Enter] to use the default:" selectSSLType case ${selectSSLType} in 1) @@ -1406,38 +1848,30 @@ switchSSLType() { sslType="letsencrypt" ;; esac + if [[ -n "${dnsAPIType}" && "${sslType}" == "buypass" ]]; then + echoContent red " ---> Give up" + exit 0 + fi echo "${sslType}" >/etc/v2ray-agent/tls/ssl_type - fi } #Select acme installation certificate method selectAcmeInstallSSL() { - local installSSLIPv6= - - if echo "${localIP}" | grep -q ":"; then - installSSLIPv6="--listen-v6" + # local sslIPv6= + # local currentIPType= + if [[ "${ipType}" == "6" ]]; then + sslIPv6="--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 + # currentIPType=$(curl -s "-${ipType}" http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) + + # if [[ -z "${currentIPType}" ]]; then + # currentIPType=$(curl -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) + # if [[ -n "${currentIPType}" ]]; then + # sslIPv6="--listen-v6" + # fi + # fi - fi acmeInstallSSL readAcmeTLS @@ -1445,44 +1879,23 @@ selectAcmeInstallSSL() { # Install SSL certificate acmeInstallSSL() { - if [[ "${dnsSSLStatus}" == "true" ]]; then - - 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 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 + local dnsAPIDomain="${tlsDomain}" + local dnsAPIExtraDomain="-d ${dnsTLSDomain}" + if [[ "${dnsAPIStatus}" == "y" ]]; then + dnsAPIDomain="*.${dnsTLSDomain}" else + dnsAPIExtraDomain="" + fi + + if [[ "${dnsAPIType}" == "cloudflare" ]]; then + echoContent green " ---> Generating certificate" + sudo CF_Token="${cfAPIToken}" "$HOME/.acme.sh/acme.sh" --issue -d "${dnsAPIDomain}" ${dnsAPIExtraDomain} --dns dns_cf -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + elif [[ "${dnsAPIType}" == "aliyun" ]]; then 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 + sudo Ali_Key="${aliKey}" Ali_Secret="${aliSecret}" "$HOME/.acme.sh/acme.sh" --issue -d "${dnsAPIDomain}" ${dnsAPIExtraDomain} --dns dns_ali -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null + else + echoContent green " ---> Certificate detected" + sudo "$HOME/.acme.sh/acme.sh" --issue -d "${tlsDomain}" --standalone -k ec-256 --server "${sslType}" ${sslIPv6} 2>&1 | tee -a /etc/v2ray-agent/tls/acme.log >/dev/null fi } # Custom port @@ -1490,39 +1903,41 @@ customPortFunction() { local historyCustomPortStatus= if [[ -n "${customPort}" || -n "${currentPort}" ]]; then echo + if [[ -z "${lastInstallationConfig}" ]]; then 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 + if [[ "${historyCustomPortStatus}" == "y" ]]; then + port=${currentPort} + echoContent yellow " --->1.Check whether the domain name is written correctly" + fi + elif [[ -n "${lastInstallationConfig}" ]]; then port=${currentPort} - echoContent yellow "\n ---> Port: ${port}" fi fi if [[ -z "${currentPort}" ]] || [[ "${historyCustomPortStatus}" == "n" ]]; then echo if [[ -n "${btDomain}" ]]; then - echoContent yellow "Please enter the port [cannot be the same as the BT Panel port, press Enter to be random]" + echoContent yellow " --->2.Check whether the domain name dns resolution is correct" 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]" + 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" read -r -p "port:" port if [[ -z "${port}" ]]; then port=443 fi - if [[ "${port}" == "${currentRealityPort}" ]]; then + if [[ "${port}" == "${xrayVLESSRealityPort}" ]]; 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}" + 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" if [[ -z "${btDomain}" ]]; then checkDNSIP "${domain}" removeNginxDefaultConf @@ -1551,43 +1966,49 @@ checkPort() { # Install TLS installTLS() { echoContent skyBlue "\nProgress$1/${totalProgress}: Apply for TLS certificate\n" + readAcmeTLS 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" + 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" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then + echoContent green " ---> Install TLS certificate, need to rely on port 80" # 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 + if [[ "${installedDNSAPIStatus}" == "true" ]]; 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 + else + 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 + else - echoContent yellow " ---> If the certificate has not expired or is customized, please select [n]\n" + if [[ -d "$HOME/.acme.sh/${tlsDomain}_ecc" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.key" && -f "$HOME/.acme.sh/${tlsDomain}_ecc/${tlsDomain}.cer" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then + if [[ -z "${lastInstallationConfig}" ]]; then + echoContent yellow " ---> Detection of abnormal return value, it is recommended to manually uninstall nginx and re-execute the script" read -r -p "Reinstall? [y/n]:" reInstallStatus - if [[ "${reInstallStatus}" == "y" ]]; then - rm -rf /etc/v2ray-agent/tls/* - installTLS "$1" + if [[ "${reInstallStatus}" == "y" ]]; then + rm -rf /etc/v2ray-agent/tls/* + installTLS "$1" + fi + fi 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, 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" + switchDNSAPI + if [[ -z "${dnsAPIType}" ]]; then + echoContent yellow " ---> Wait three minutes after closing the cloud and try again" + echoContent green " ---> TLS generated successfully" + allowPort 80 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 + + switchSSLType + customSSLEmail + selectAcmeInstallSSL + + if [[ "${installedDNSAPIStatus}" == "true" ]]; 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 + else 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 @@ -1611,9 +2032,9 @@ installTLS() { fi fi - echoContent green " ---> TLS generated successfully" + echoContent green " ---> Used successfully\n" else - echoContent yellow " ---> acme.sh is not installed" + echoContent yellow " ---> The detected IP is as follows: [${localIP}]" exit 0 fi } @@ -1631,19 +2052,25 @@ initRandomPath() { # Custom/random path randomPathFunction() { + if [[ -n $1 ]]; then echoContent skyBlue "\nProgress$1/${totalProgress}: Generate random path" + else + echoContent skyBlue "\n----------------------------" + fi - if [[ -n "${currentPath}" ]]; then + if [[ -n "${currentPath}" && -z "${lastInstallationConfig}" ]]; 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 + elif [[ -n "${currentPath}" && -n "${lastInstallationConfig}" ]]; then + historyPathStatus="y" fi if [[ "${historyPathStatus}" == "y" ]]; then customPath=${currentPath} - echoContent green " ---> Used successfully\n" + echoContent green " ---> Added fake site successfully" else - echoContent yellow "Please enter a custom path [eg: alone], no slash required, [Enter] random path" + echoContent yellow "Please re-enter the correct email format [Example: username@example.com]" read -r -p 'path:' customPath if [[ -z "${customPath}" ]]; then initRandomPath @@ -1661,27 +2088,59 @@ randomPathFunction() { echoContent yellow "\n path:${currentPath}" echoContent skyBlue "\n----------------------------" } +randomNum() { + if [[ "${release}" == "alpine" ]]; then + local ranNum= + ranNum="$(shuf -i "$1"-"$2" -n 1)" + echo "${ranNum}" + else + echo $((RANDOM % $2 + $1)) + fi +} # Nginx disguise blog nginxBlog() { + if [[ -n "$1" ]]; then echoContent skyBlue "\nProgress$1/${totalProgress}: Add fake site" + else + echoContent yellow "1.letsencrypt[default]" + fi + if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then echo + if [[ -z "${lastInstallationConfig}" ]]; then read -r -p "Detected installation of fake site, do you need to reinstall [y/n]:" nginxBlogInstallStatus + else + nginxBlogInstallStatus="n" + fi + 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 + rm -rf "${nginxStaticPath}*" + # randomNum=$((RANDOM % 6 + 1)) + randomNum=$(randomNum 1 9) + if [[ "${release}" == "alpine" ]]; then + wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip" + else + wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip" + fi + unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null rm -f "${nginxStaticPath}html${randomNum}.zip*" - echoContent green " ---> Added fake site successfully" + 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 + randomNum=$(randomNum 1 9) + # randomNum=$((RANDOM % 6 + 1)) + rm -rf "${nginxStaticPath}*" + + if [[ "${release}" == "alpine" ]]; then + wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip" + else + wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${randomNum}.zip" + fi + unzip -o "${nginxStaticPath}html${randomNum}.zip" -d "${nginxStaticPath}" >/dev/null rm -f "${nginxStaticPath}html${randomNum}.zip*" - echoContent green " ---> Added fake site successfully" + echoContent green " ---> http_port_t 31300 port opened successfully" fi } @@ -1695,12 +2154,12 @@ updateSELinuxHTTPPortT() { echoContent red " ---> 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" + echoContent green " ---> http_port_t 31302 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" + echoContent green " ---> Nginx started successfully" fi handleNginx start @@ -1712,31 +2171,39 @@ updateSELinuxHTTPPortT() { #Operation Nginx handleNginx() { - if [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then - systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log + if ! echo "${selectCustomInstallType}" | grep -qwE ",7,|,8,|,7,8," && [[ -z $(pgrep -f "nginx") ]] && [[ "$1" == "start" ]]; then + if [[ "${release}" == "alpine" ]]; then + rc-service nginx start 2>/etc/v2ray-agent/nginx_error.log + else + systemctl start nginx 2>/etc/v2ray-agent/nginx_error.log + fi 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" - + nginx if grep -q "journalctl -xe" Nginx started successfully" + echoContent green " ---> Nginx closed successfully" fi elif [[ -n $(pgrep -f "nginx") ]] && [[ "$1" == "stop" ]]; then - systemctl stop nginx + + if [[ "${release}" == "alpine" ]]; then + rc-service nginx stop + else + systemctl stop nginx + fi sleep 0.5 - if [[ -n $(pgrep -f "nginx") ]]; then + + if [[ -z ${btDomain} && -n $(pgrep -f "nginx") ]]; then pgrep -f "nginx" | xargs kill -9 fi - echoContent green " ---> Nginx closed successfully" + echoContent green "\n ---> Add scheduled maintenance certificate successfully" fi } @@ -1750,12 +2217,12 @@ installCronTLS() { 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" + echoContent green "\n ---> Adding scheduled update geo file successfully" fi } # Scheduled tasks update geo files installCronUpdateGeo() { - if [[ -n "${configPath}" ]]; then + if [[ "${coreInstallType}" == "1" ]]; 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 @@ -1764,7 +2231,7 @@ installCronUpdateGeo() { 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" + echoContent green " ---> The certificate is valid" fi } @@ -1785,10 +2252,10 @@ renewalTLS() { 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 + if [[ -d "$HOME/.acme.sh/${domain}_ecc" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.key" && -f "$HOME/.acme.sh/${domain}_ecc/${domain}.cer" ]] || [[ "${installedDNSAPIStatus}" == "true" ]]; then modifyTime= - if [[ "${installDNSACMEStatus}" == "true" ]]; then + if [[ "${installedDNSAPIStatus}" == "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") @@ -1812,141 +2279,90 @@ renewalTLS() { 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" + echoContent yellow "2.zerossl" handleNginx stop if [[ "${coreInstallType}" == "1" ]]; then handleXray stop elif [[ "${coreInstallType}" == "2" ]]; then - handleV2Ray stop + handleSingBox 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 + 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" + echoContent green " ---> v2ray-core version:${version}" fi + elif [[ -f "/etc/v2ray-agent/tls/${tlsDomain}.crt" && -f "/etc/v2ray-agent/tls/${tlsDomain}.key" && -n $(cat "/etc/v2ray-agent/tls/${tlsDomain}.crt") ]]; then + echoContent yellow "3.buypass[Does not support DNS application]" else echoContent red " ---> not installed" fi } -# 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}') - - modifyTime=$(date +%s -d "${modifyTime}") - currentTime=$(date +%s) - ((stampDiff = currentTime - modifyTime)) - ((days = stampDiff / 86400)) - ((remainingDays = sslRenewalDays - days)) - - tlsStatus=${remainingDays} - if [[ ${remainingDays} -le 0 ]]; then - tlsStatus="Expired" - fi - - echoContent skyBlue " ---> Certificate generation date: $(date -d "@${modifyTime}" +"%F %H:%M:%S")" - echoContent skyBlue " ---> Certificate generation days: ${days}" - echoContent skyBlue " ---> Number of days remaining on the certificate:${tlsStatus}" - fi -} - -#Install V2Ray, specified version -installV2Ray() { +installSingBox() { readInstallType - echoContent skyBlue "\nProgress$1/${totalProgress}: Install V2Ray" + echoContent skyBlue " ---> Certificate generation days: ${days}" - if [[ "${coreInstallType}" != "2" && "${coreInstallType}" != "3" ]]; then - if [[ "${selectCoreType}" == "2" ]]; then + if [[ ! -f "/etc/v2ray-agent/sing-box/sing-box" ]]; then - 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) + if [[ "${prereleaseStatus}" == "true" ]]; then + version=$(curl -s "https://api.github.com/repos/SagerNet/sing-box/releases?per_page=20" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) else - version=${v2rayCoreVersion} + version=$(curl -s https://api.github.com/repos/SagerNet/sing-box/releases/latest | jq -r .tag_name) 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" + + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P /etc/v2ray-agent/sing-box/ "https://github.com/SagerNet/sing-box/releases/download/${version}/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" else + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/sing-box/ "https://github.com/SagerNet/sing-box/releases/download/${version}/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" + fi + + if [[ ! -f "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" ]]; then + read -r -p "Core download failed. Retry installation? [y/n]" downloadStatus + if [[ "${downloadStatus}" == "y" ]]; then + installSingBox "$1" + fi + else + + tar zxvf "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}.tar.gz" -C "/etc/v2ray-agent/sing-box/" >/dev/null 2>&1 + + mv "/etc/v2ray-agent/sing-box/sing-box-${version/v/}${singBoxCoreCPUVendor}/sing-box" /etc/v2ray-agent/sing-box/sing-box + rm -rf /etc/v2ray-agent/sing-box/sing-box-* + chmod 655 /etc/v2ray-agent/sing-box/sing-box + fi + else + echoContent green " ---> Current version:v$(/etc/v2ray-agent/sing-box/sing-box version | grep "sing-box version" | awk '{print $3}')" + + if [[ "${prereleaseStatus}" == "true" ]]; then + version=$(curl -s "https://api.github.com/repos/SagerNet/sing-box/releases?per_page=20" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) + else + version=$(curl -s https://api.github.com/repos/SagerNet/sing-box/releases/latest | jq -r .tag_name) + fi + 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" + + if [[ -z "${lastInstallationConfig}" ]]; then + read -r -p "Update or upgrade? [y/n]:" reInstallSingBoxStatus + if [[ "${reInstallSingBoxStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/sing-box/sing-box + installSingBox "$1" fi fi fi -} - -# Install hysteria -installHysteria() { - readInstallType - echoContent skyBlue "\nProgress$1/${totalProgress}: Installing Hysteria" - - if [[ -z "${hysteriaConfigPath}" ]]; then - - 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}" - 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 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" + if [[ "${release}" != "alpine" ]]; then + if find /usr/bin /usr/sbin | grep -q "/wget" && wget --help | grep -q show-progress; then + wgetShowProgressStatus="--show-progress" + fi fi } # Install xray @@ -1957,135 +2373,102 @@ installXray() { prereleaseStatus=true fi - echoContent skyBlue "\nProgress$1/${totalProgress}: Install Xray" + echoContent skyBlue " ---> Number of days remaining on the certificate:${tlsStatus}" - if [[ "${coreInstallType}" != "1" ]]; then - - version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1" | jq -r ".[].tag_name") - - 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 " ---> 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}" + if [[ ! -f "/etc/v2ray-agent/xray/xray" ]]; then + if [[ "${prereleaseStatus}" == "true" ]]; then + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) else - echoContent red "\n ---> Incorrect input, please re-enter" - v2rayVersionManageMenu 1 + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases/latest | jq -r .tag_name) + fi + + echoContent green " ---> Hysteria version:${version}" + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + else + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + fi + + if [[ ! -f "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" ]]; then + read -r -p "Core download failed. Retry installation? [y/n]" downloadStatus + if [[ "${downloadStatus}" == "y" ]]; then + installXray "$1" + fi + else + 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 + + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat" + wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat" + else + 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" + fi + + chmod 655 /etc/v2ray-agent/xray/xray + fi + else + if [[ -z "${lastInstallationConfig}" ]]; then + 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]:" reInstallXrayStatus + if [[ "${reInstallXrayStatus}" == "y" ]]; then + rm -f /etc/v2ray-agent/xray/xray + installXray "$1" "$2" + fi 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 " ---> The installation directory is not detected, please execute the script to install the content" - menu + echoContent skyBlue "\nProgress$1/${totalProgress}: Install V2Ray" + if [[ "${coreInstallType}" != "1" ]]; then + echoContent red " ---> Core download failed, please try installation again" 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 "================================================== ===============" + echoContent red "\n==============================================================" + 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 yellow " ---> Please wait 1-2 minutes after the addition is completed" + echoContent yellow "\n ---> Port: ${port}" + echoContent yellow "Please enter the port [cannot be the same as the BT Panel port, press Enter to be random]" + echoContent yellow "Please enter the port [default: 443], you can customize the port [press Enter to use the default]" + echoContent yellow "\n ---> Port: ${port}" + echoContent yellow " ---> If the certificate has not expired or is customized, please select [n]\n" + echoContent yellow " ---> acme.sh is not installed" + echoContent red "==============================================================" read -r -p "Please select:" selectXrayType if [[ "${selectXrayType}" == "1" ]]; then + prereleaseStatus=false updateXray elif [[ "${selectXrayType}" == "2" ]]; then - prereleaseStatus=true updateXray - 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 yellow "Please enter a custom path [eg: alone], no slash required, [Enter] random path" + echoContent yellow "\n path:${currentPath}" + echoContent yellow " ---> Regenerate certificate" 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 "------------------------------------------------- ---------------" + 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" + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" xrayVersionManageMenu 1 fi elif [[ "${selectXrayType}" == "4" ]]; then handleXray stop elif [[ "${selectXrayType}" == "5" ]]; then + # start up handleXray start elif [[ "${selectXrayType}" == "6" ]]; then reloadCore @@ -2093,113 +2476,56 @@ xrayVersionManageMenu() { updateGeoSite elif [[ "${selectXrayType}" == "8" ]]; then installCronUpdateGeo + elif [[ "${selectXrayType}" == "9" ]]; then + checkLog 1 fi } # Update geosite updateGeoSite() { - echoContent yellow "\nSource https://github.com/Loyalsoldier/v2ray-rules-dat" + echoContent yellow "1.Upgrade v2ray-core" 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 - - 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 - - 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 + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geosite.dat" + wget -c -q -P ${configPath}../ "https://github.com/Loyalsoldier/v2ray-rules-dat/releases/download/${version}/geoip.dat" 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 "${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 - - 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 - - fi + 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" fi + + reloadCore + echoContent green " ---> Tuic version:${version}" + } # Update Xray updateXray() { readInstallType - if [[ -z "${coreInstallType}" ]]; then - if [[ -n "$1" ]]; then - version=$1 + + if [[ -z "${coreInstallType}" || "${coreInstallType}" != "1" ]]; then + + if [[ "${prereleaseStatus}" == "true" ]]; then + version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) else - version=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=1" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name") + version=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases/latest | jq -r .tag_name) fi - echoContent green " ---> Xray-core version:${version}" + if [[ -n "$1" ]]; then + version=$1 + fi - wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + echoContent green " ---> Tuic version:$(/etc/v2ray-agent/tuic/tuic -v)" + + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + else + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/xray/ "https://github.com/XTLS/Xray-core/releases/download/${version}/${xrayCoreCPUVendor}.zip" + fi unzip -o "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" -d /etc/v2ray-agent/xray >/dev/null rm -rf "/etc/v2ray-agent/xray/${xrayCoreCPUVendor}.zip" @@ -2207,42 +2533,49 @@ updateXray() { handleXray stop handleXray start else - echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + echoContent green " ---> Xray-core version:${version}" + + if [[ "${prereleaseStatus}" == "true" ]]; then + remoteVersion=$(curl -s "https://api.github.com/repos/XTLS/Xray-core/releases?per_page=5" | jq -r ".[]|select (.prerelease==${prereleaseStatus})|.tag_name" | head -1) + else + remoteVersion=$(curl -s https://api.github.com/repos/XTLS/Xray-core/releases/latest | jq -r .tag_name) + fi + + echoContent green " ---> 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?per_page=1" | jq -r ".[].tag_name") + version=${remoteVersion} 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)" + echoContent green " ---> Update completed" handleXray stop rm -f /etc/v2ray-agent/xray/xray updateXray "${version}" else - echoContent green " ---> Abandon the rollback version" + echoContent green " ---> v2ray-core version:${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" + echoContent green " ---> Current v2ray-core version: $(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" 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 + rm /etc/v2ray-agent/xray/xray updateXray else - echoContent green " ---> Abort update" + echoContent green " ---> Current v2ray-core version: $(/etc/v2ray-agent/v2ray/v2ray --version | awk '{print $2}' | head -1)" fi fi @@ -2252,113 +2585,88 @@ updateXray() { # Verify that the entire service is available checkGFWStatue() { readInstallType - echoContent skyBlue "\nProgress$1/${totalProgress}: Verify service startup status" + echoContent skyBlue "\nProgress$1/${totalProgress}: Installing Hysteria" 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" + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" + elif [[ "${coreInstallType}" == "2" ]] && [[ -n $(pgrep -f "sing-box/sing-box") ]]; then + echoContent green " ---> Abandon the rollback version" else - echoContent red " ---> Service startup failed, please check if there are logs printed in the terminal" + echoContent red "\n================================================ =================" exit 0 fi - } -# V2Ray starts automatically after booting -installV2RayService() { - 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 +installAlpineStartup() { + local serviceName=$1 + if [[ "${serviceName}" == "sing-box" ]]; then + cat <"/etc/init.d/${serviceName}" +#!/sbin/openrc-run + +description="sing-box service" +command="/etc/v2ray-agent/sing-box/sing-box" +command_args="run -c /etc/v2ray-agent/sing-box/conf/config.json" +command_background=true +pidfile="/var/run/sing-box.pid" +EOF + elif [[ "${serviceName}" == "xray" ]]; then + cat <"/etc/init.d/${serviceName}" +#!/sbin/openrc-run + +description="xray service" +command="/etc/v2ray-agent/xray/xray" +command_args="run -confdir /etc/v2ray-agent/xray/conf" +command_background=true +pidfile="/var/run/xray.pid" +EOF + fi + + chmod +x "/etc/init.d/${serviceName}" +} + +installSingBoxService() { + echoContent skyBlue "\nProgress$1/${totalProgress}: Install Tuic" + execStart='/etc/v2ray-agent/sing-box/sing-box run -c /etc/v2ray-agent/sing-box/conf/config.json' + + if [[ -n $(find /bin /usr/bin -name "systemctl") && "${release}" != "alpine" ]]; then + rm -rf /etc/systemd/system/sing-box.service + touch /etc/systemd/system/sing-box.service + cat </etc/systemd/system/sing-box.service [Unit] -Description=V2Ray - A unified platform for anti-censorship -Documentation=https://v2ray.com https://guide.v2fly.org +Description=Sing-Box Service +Documentation=https://sing-box.sagernet.org 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 +WorkingDirectory=/root +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH +AmbientCapabilities=CAP_NET_ADMIN CAP_NET_BIND_SERVICE CAP_SYS_PTRACE CAP_DAC_READ_SEARCH ExecStart=${execStart} +ExecReload=/bin/kill -HUP $MAINPID Restart=on-failure -RestartPreventExitStatus=23 -LimitNPROC=10000 -LimitNOFILE=1000000 +RestartSec=10 +LimitNPROC=infinity +LimitNOFILE=infinity [Install] WantedBy=multi-user.target EOF - systemctl daemon-reload - systemctl enable v2ray.service - echoContent green " ---> Configure V2Ray to start automatically at boot" + bootStartup "sing-box.service" + elif [[ "${release}" == "alpine" ]]; then + installAlpineStartup "sing-box" + bootStartup "sing-box" fi + + echoContent green " ---> Give up and reinstall" } -# Install hysteria to start automatically at boot -installHysteriaService() { - 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=Hysteria Service -Documentation=https://github.com/apernet -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 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" + echoContent skyBlue "\nProgress$1/${totalProgress}: Install Xray" + execStart='/etc/v2ray-agent/xray/xray run -confdir /etc/v2ray-agent/xray/conf' 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 @@ -2369,50 +2677,22 @@ User=root ExecStart=${execStart} Restart=on-failure RestartPreventExitStatus=23 -LimitNPROC=10000 -LimitNOFILE=1000000 +LimitNPROC=infinity +LimitNOFILE=infinity [Install] WantedBy=multi-user.target EOF - systemctl daemon-reload - systemctl enable xray.service - echoContent green " ---> Configure Xray to start automatically at boot" - fi -} - -#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 - - 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 + bootStartup "xray.service" + echoContent green " ---> Abort update" + elif [[ "${release}" == "alpine" ]]; then + installAlpineStartup "xray" + bootStartup "xray" fi } # Operation Hysteria handleHysteria() { + # shellcheck disable=SC2010 # 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 @@ -2425,52 +2705,62 @@ handleHysteria() { if [[ "$1" == "start" ]]; then if [[ -n $(pgrep -f "hysteria/hysteria") ]]; then - echoContent green " ---> Hysteria started successfully" + echoContent green " ---> Xray-core version:${version}" 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" + echoContent red "================================================== ===============" + echoContent red "\n ---> Incorrect input, please re-enter" exit 0 fi elif [[ "$1" == "stop" ]]; then if [[ -z $(pgrep -f "hysteria/hysteria") ]]; then - echoContent green " ---> Hysteria closed successfully" + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" else - echoContent red "Hysteria shutdown failed" - echoContent red "Please execute manually [ps -ef|grep -v grep|grep hysteria|awk '{print \$2}'|xargs kill -9]" + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + echoContent red "\n================================================ =================" 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 + +handleSingBox() { + if [[ -f "/etc/systemd/system/sing-box.service" ]]; then + if [[ -z $(pgrep -f "sing-box") ]] && [[ "$1" == "start" ]]; then + singBoxMergeConfig + systemctl start sing-box.service + elif [[ -n $(pgrep -f "sing-box") ]] && [[ "$1" == "stop" ]]; then + systemctl stop sing-box.service + fi + elif [[ -f "/etc/init.d/sing-box" ]]; then + if [[ -z $(pgrep -f "sing-box") ]] && [[ "$1" == "start" ]]; then + singBoxMergeConfig + rc-service sing-box start + elif [[ -n $(pgrep -f "sing-box") ]] && [[ "$1" == "stop" ]]; then + rc-service sing-box stop fi fi - sleep 0.8 + sleep 1 if [[ "$1" == "start" ]]; then - if [[ -n $(pgrep -f "tuic/tuic") ]]; then - echoContent green " ---> Tuic started successfully" + if [[ -n $(pgrep -f "sing-box") ]]; then + echoContent green " ---> Current Xray-core version: $(/etc/v2ray-agent/xray/xray --version | awk '{print $2}' | head -1)" 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" + echoContent red "================================================== ===============" + echoContent yellow "2.Fallback v2ray-core" + echo + echoContent yellow "3.Close v2ray-core" exit 0 fi elif [[ "$1" == "stop" ]]; then - if [[ -z $(pgrep -f "tuic/tuic") ]]; then - echoContent green " ---> Tuic closed successfully" + if [[ -z $(pgrep -f "sing-box") ]]; then + echoContent green " ---> Abandon the rollback version" 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]" + echoContent red "\n ---> Incorrect input, please re-enter" + echoContent red " ---> Service startup failed, please check if there are logs printed in the terminal" exit 0 fi fi } + # Manipulate xray handleXray() { if [[ -n $(find /bin /usr/bin -name "systemctl") ]] && [[ -n $(find /etc/systemd/system/ -name "xray.service") ]]; then @@ -2479,24 +2769,30 @@ handleXray() { elif [[ -n $(pgrep -f "xray/xray") ]] && [[ "$1" == "stop" ]]; then systemctl stop xray.service fi + elif [[ -f "/etc/init.d/xray" ]]; then + if [[ -z $(pgrep -f "xray/xray") ]] && [[ "$1" == "start" ]]; then + rc-service xray start + elif [[ -n $(pgrep -f "xray/xray") ]] && [[ "$1" == "stop" ]]; then + rc-service xray stop + fi fi sleep 0.8 if [[ "$1" == "start" ]]; then if [[ -n $(pgrep -f "xray/xray") ]]; then - echoContent green " ---> Xray started successfully" + echoContent green " ---> Give up and reinstall" 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" + 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 "xray/xray") ]]; then - echoContent green " ---> Xray closed successfully" + echoContent green " ---> Abort update" 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]" + 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 @@ -2504,915 +2800,986 @@ handleXray() { # Read user data and initialize initXrayClients() { - local type=$1 + 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\"}" + 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 - + users=[] while read -r user; do - uuid=$(echo "${user}" | jq -r .id) - email=$(echo "${user}" | jq -r .email | awk -F "[-]" '{print $1}') + uuid=$(echo "${user}" | jq -r .id//.uuid) + email=$(echo "${user}" | jq -r .email//.name | 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 + # VLESS WS + 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 + # VLESS XHTTP + if echo "${type}" | grep -q ",12,"; then + currentUser="{\"id\":\"${uuid}\",\"email\":\"${email}-VLESS_Reality_XHTTP\"}" + 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 + # VMess WS + 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 + # trojan tcp + 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 + 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}\"]") + if echo "${type}" | grep -q ",6,"; then + currentUser="{\"password\":\"${uuid}\",\"name\":\"${email}-singbox_hysteria2\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") fi # vless reality vision - if echo "${type}" | grep -q "7"; then + 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 + 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}\"") + if echo "${type}" | grep -q ",9,"; then + currentUser="{\"uuid\":\"${uuid}\",\"password\":\"${uuid}\",\"name\":\"${email}-singbox_tuic\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") fi done < <(echo "${currentClients}" | jq -c '.[]') echo "${users}" } -getClients() { - local path=$1 +initSingBoxClients() { + local type=",$1," + local newUUID=$2 + local newName=$3 - 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 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}") + if [[ -n "${newUUID}" ]]; then + local newUser= + newUser="{\"uuid\":\"${newUUID}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${newName}-VLESS_TCP/TLS_Vision\"}" + currentClients=$(echo "${currentClients}" | jq -r ". +=[${newUser}]") + fi + local users= + users=[] + while read -r user; do + uuid=$(echo "${user}" | jq -r .uuid//.id//.password) + name=$(echo "${user}" | jq -r .name//.email//.username | awk -F "[-]" '{print $1}') + currentUser= + # VLESS Vision + if echo "${type}" | grep -q ",0,"; then + currentUser="{\"uuid\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${name}-VLESS_TCP/TLS_Vision\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # VLESS WS + if echo "${type}" | grep -q ",1,"; then + currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VLESS_WS\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # VMess ws + if echo "${type}" | grep -q ",3,"; then + currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VMess_WS\",\"alterId\": 0}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") fi - fi -} - -#Add client configuration -addClients() { - - local path=$1 - local addClientsStatus=$2 - if [[ ${addClientsStatus} == "true" && -n "${previousClients}" ]]; then - config=$(jq -r ".inbounds[0].settings.clients = ${previousClients}" "${path}") - echo "${config}" | jq . >"${path}" - fi -} -# Add hysteria configuration -addClientsHysteria() { - local path=$1 - local addClientsStatus=$2 - - if [[ ${addClientsStatus} == "true" && -n "${previousClients}" ]]; then - local uuids= - uuids=$(echo "${previousClients}" | jq -r [.[].id]) - - if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then - uuids=$(echo "${previousClients}" | jq -r [.[].password]) + # trojan + if echo "${type}" | grep -q ",4,"; then + currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-Trojan_TCP\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") fi - config=$(jq -r ".auth.config = ${uuids}" "${path}") - echo "${config}" | jq . >"${path}" - fi + + # VLESS Reality Vision + if echo "${type}" | grep -q ",7,"; then + currentUser="{\"uuid\":\"${uuid}\",\"flow\":\"xtls-rprx-vision\",\"name\":\"${name}-VLESS_Reality_Vision\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # VLESS Reality gRPC + if echo "${type}" | grep -q ",8,"; then + currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VLESS_Reality_gPRC\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # hysteria2 + if echo "${type}" | grep -q ",6,"; then + currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-singbox_hysteria2\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # tuic + if echo "${type}" | grep -q ",9,"; then + currentUser="{\"uuid\":\"${uuid}\",\"password\":\"${uuid}\",\"name\":\"${name}-singbox_tuic\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + # naive + if echo "${type}" | grep -q ",10,"; then + currentUser="{\"password\":\"${uuid}\",\"username\":\"${name}-singbox_naive\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # VMess HTTPUpgrade + if echo "${type}" | grep -q ",11,"; then + currentUser="{\"uuid\":\"${uuid}\",\"name\":\"${name}-VMess_HTTPUpgrade\",\"alterId\": 0}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + # anytls + if echo "${type}" | grep -q ",13,"; then + currentUser="{\"password\":\"${uuid}\",\"name\":\"${name}-anytls\"}" + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + if echo "${type}" | grep -q ",20,"; then + currentUser="{\"username\":\"${uuid}\",\"password\":\"${uuid}\"}" + + users=$(echo "${users}" | jq -r ". +=[${currentUser}]") + fi + + done < <(echo "${currentClients}" | jq -c '.[]') + echo "${users}" } #Initialize hysteria port initHysteriaPort() { - readHysteriaConfig + readSingBoxConfig 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}" + echoContent yellow "4.Open v2ray-core" else hysteriaPort= fi fi if [[ -z "${hysteriaPort}" ]]; then - echoContent yellow "Please enter the Hysteria port [enter random 10000-30000], cannot be repeated with other services" + echoContent yellow "5.Restart v2ray-core" 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" + echoContent red "Hysteria startup failed" initHysteriaPort "$2" elif ((hysteriaPort < 1 || hysteriaPort > 65535)); then - echoContent red " ---> The port is illegal" + 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" initHysteriaPort "$2" fi allowPort "${hysteriaPort}" allowPort "${hysteriaPort}" "udp" } -# Initialize hysteria protocol -initHysteriaProtocol() { - 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" -} +initHysteria2Network() { -# Initialize hysteria network information -initHysteriaNetwork() { - - 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" + echoContent yellow "6.Update geosite, geoip" + read -r -p "Download speed:" hysteria2ClientDownloadSpeed + if [[ -z "${hysteria2ClientDownloadSpeed}" ]]; then + hysteria2ClientDownloadSpeed=100 + echoContent green " ---> Service started successfully" 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" + echoContent yellow "7.Set up automatic update of geo files [updated every morning]" + read -r -p "Upload speed:" hysteria2ClientUploadSpeed + if [[ -z "${hysteria2ClientUploadSpeed}" ]]; then + hysteria2ClientUploadSpeed=50 + echoContent green " ---> Service started successfully" 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 -{ - "hysteriaLag":"${hysteriaLag}", - "hysteriaClientUploadSpeed":"${hysteriaClientUploadSpeed}", - "hysteriaClientDownloadSpeed":"${hysteriaClientDownloadSpeed}" -} -EOF - } -# hy port jump -hysteriaPortHopping() { +addFirewalldPortHopping() { + + local start=$1 + local end=$2 + local targetPort=$3 + for port in $(seq "$start" "$end"); do + sudo firewall-cmd --permanent --add-forward-port=port="${port}":proto=udp:toport="${targetPort}" + done + sudo firewall-cmd --reload +} + +addPortHopping() { + local type=$1 + local targetPort=$2 if [[ -n "${portHoppingStart}" || -n "${portHoppingEnd}" ]]; then - echoContent red " ---> Already added, cannot be added repeatedly, can be deleted and re-added" + echoContent red "Hysteria shutdown failed" exit 0 fi + if [[ "${release}" == "centos" ]]; then + if ! systemctl status firewalld 2>/dev/null | grep -q "active (running)"; then + echoContent red "Please execute manually [ps -ef|grep -v grep|grep hysteria|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi + 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 skyBlue "------------------------Version-------------------------------" + echoContent red "\n==============================================================" + 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 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 "Please enter the port jumping range, for example [30000-31000]" + echoContent yellow "5.Open Xray-core" - read -r -p "Range:" hysteriaPortHoppingRange - if [[ -z "${hysteriaPortHoppingRange}" ]]; then - echoContent red " ---> Range cannot be empty" - hysteriaPort Hopping - elif echo "${hysteriaPortHoppingRange}" | grep -q "-"; then + read -r -p "Range:" portHoppingRange + if [[ -z "${portHoppingRange}" ]]; then + echoContent red "Tuic startup failed" + addPortHopping "${type}" "${targetPort}" + elif echo "${portHoppingRange}" | grep -q "-"; then local portStart= local portEnd= - portStart=$(echo "${hysteriaPortHoppingRange}" | awk -F '-' '{print $1}') - portEnd=$(echo "${hysteriaPortHoppingRange}" | awk -F '-' '{print $2}') + portStart=$(echo "${portHoppingRange}" | awk -F '-' '{print $1}') + portEnd=$(echo "${portHoppingRange}" | 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 + echoContent red "Please manually execute [/etc/v2ray-agent/tuic/tuic -c /etc/v2ray-agent/tuic/conf/config.json] and check the error log" + addPortHopping "${type}" "${targetPort}" + elif ((portStart < 30000 || portStart > 40000 || portEnd < 30000 || portEnd > 40000 || portEnd < portStart)); then + echoContent red "Tuic failed to close" + addPortHopping "${type}" "${targetPort}" 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" + echoContent green " ---> Configure V2Ray to start automatically at boot" + if [[ "${release}" == "centos" ]]; then + sudo firewall-cmd --permanent --add-masquerade + sudo firewall-cmd --reload + addFirewalldPortHopping "${portStart}" "${portEnd}" "${targetPort}" + if ! sudo firewall-cmd --list-forward-ports | grep -q "toport=${targetPort}"; then + echoContent red "Please execute manually [ps -ef|grep -v grep|grep tuic|awk '{print \$2}'|xargs kill -9]" + exit 0 + fi else - echoContent red " ---> Failed to add port hopping" + iptables -t nat -A PREROUTING -p udp --dport "${portStart}:${portEnd}" -m comment --comment "mack-a_${type}_portHopping" -j DNAT --to-destination ":${targetPort}" + sudo netfilter-persistent save + if ! iptables-save | grep -q "mack-a_${type}_portHopping"; then + echoContent red "Xray startup failed" + exit 0 + fi fi - # fi + allowPort "${portStart}:${portEnd}" udp + echoContent green " ---> Configure Hysteria to start automatically at boot" 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) +readPortHopping() { + local type=$1 + local targetPort=$2 + local portHoppingStart= + local portHoppingEnd= + + if [[ "${release}" == "centos" ]]; then + portHoppingStart=$(sudo firewall-cmd --list-forward-ports | grep "toport=${targetPort}" | head -1 | cut -d ":" -f 1 | cut -d "=" -f 2) + portHoppingEnd=$(sudo firewall-cmd --list-forward-ports | grep "toport=${targetPort}" | tail -n 1 | cut -d ":" -f 1 | cut -d "=" -f 2) + else + if iptables-save | grep -q "mack-a_${type}_portHopping"; then + local portHopping= + portHopping=$(iptables-save | grep "mack-a_${type}_portHopping" | cut -d " " -f 8) + portHoppingStart=$(echo "${portHopping}" | cut -d ":" -f 1) portHoppingEnd=$(echo "${portHopping}" | cut -d ":" -f 2) fi fi + if [[ "${type}" == "hysteria2" ]]; then + hysteria2PortHoppingStart="${portHoppingStart}" + hysteria2PortHoppingEnd=${portHoppingEnd} + hysteria2PortHopping="${portHoppingStart}-${portHoppingEnd}" + elif [[ "${type}" == "tuic" ]]; then + tuicPortHoppingStart="${portHoppingStart}" + tuicPortHoppingEnd="${portHoppingEnd}" + # tuicPortHopping="${portHoppingStart}-${portHoppingEnd}" + fi +} +deletePortHoppingRules() { + local type=$1 + local start=$2 + local end=$3 + local targetPort=$4 + + if [[ "${release}" == "centos" ]]; then + for port in $(seq "${start}" "${end}"); do + sudo firewall-cmd --permanent --remove-forward-port=port="${port}":proto=udp:toport="${targetPort}" + done + sudo firewall-cmd --reload + else + iptables -t nat -L PREROUTING --line-numbers | grep "mack-a_${type}_portHopping" | awk '{print $1}' | while read -r line; do + iptables -t nat -D PREROUTING 1 + sudo netfilter-persistent save + done + 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() { +portHoppingMenu() { + local type=$1 # 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" + 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 - 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" + + local targetPort= + local portHoppingStart= + local portHoppingEnd= + + if [[ "${type}" == "hysteria2" ]]; then + readPortHopping "${type}" "${singBoxHysteria2Port}" + targetPort=${singBoxHysteria2Port} + portHoppingStart=${hysteria2PortHoppingStart} + portHoppingEnd=${hysteria2PortHoppingEnd} + elif [[ "${type}" == "tuic" ]]; then + readPortHopping "${type}" "${singBoxTuicPort}" + targetPort=${singBoxTuicPort} + portHoppingStart=${tuicPortHoppingStart} + portHoppingEnd=${tuicPortHoppingEnd} + fi + + echoContent skyBlue "\nProgress$1/${totalProgress}: V2Ray version management" + echoContent red "\n==============================================================" + 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]" read -r -p "range:" selectPortHoppingStatus if [[ "${selectPortHoppingStatus}" == "1" ]]; then - hysteriaPort Hopping + addPortHopping "${type}" "${targetPort}" elif [[ "${selectPortHoppingStatus}" == "2" ]]; then - if [[ -n "${portHopping}" ]]; then - deleteHysteriaPortHoppingRules - echoContent green " ---> Deletion successful" - fi + deletePortHoppingRules "${type}" "${portHoppingStart}" "${portHoppingEnd}" "${targetPort}" + echoContent green " ---> Configuring Tuic to start automatically at boot" elif [[ "${selectPortHoppingStatus}" == "3" ]]; then - echoContent green " ---> The current port hopping range is: ${portHoppingStart}-${portHoppingEnd}" + if [[ -n "${portHoppingStart}" && -n "${portHoppingEnd}" ]]; then + echoContent green " ---> Configure Xray to start automatically at boot" + else + echoContent yellow "\n1.Only the last five versions can be rolled back" + fi else - hysteriaPortHoppingMenu + portHoppingMenu fi } -#Initialize Hysteria configuration -initHysteriaConfig() { - echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Hysteria configuration" - - 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}", - "disable_udp": false, - "cert": "/etc/v2ray-agent/tls/${currentHost}.crt", - "key": "/etc/v2ray-agent/tls/${currentHost}.key", - "auth": { - "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, - "max_conn_client": 4096, - "disable_mtu_discovery": true, - "resolve_preference": "46", - "resolver": "https://8.8.8.8:443/dns-query" -} -EOF - - addClientsHysteria "/etc/v2ray-agent/hysteria/conf/config.json" true - - # 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 tuic port initTuicPort() { - readTuicConfig + readSingBoxConfig 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}" + echoContent yellow "2.There is no guarantee that it will be able to be used normally after the rollback" 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" + echoContent yellow "3.If the rolled-back version does not support the current config, it will be unable to connect, so operate with caution" 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" + echoContent red "xray failed to close" initTuicPort "$2" elif ((tuicPort < 1 || tuicPort > 65535)); then - echoContent red " ---> The port is illegal" + echoContent red "Please execute manually [ps -ef|grep -v grep|grep xray|awk '{print \$2}'|xargs kill -9]" initTuicPort "$2" fi - echoContent green "\n ---> Port: ${tuicPort}" + echoContent green " ---> V2Ray started successfully" 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}: Initializing V2Ray configuration" - echo - - 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 + if [[ -n "${tuicAlgorithm}" && -z "${lastInstallationConfig}" ]]; then + read -r -p "Previous algorithm found. Use it? [y/n]:" historyTuicAlgorithm + if [[ "${historyTuicAlgorithm}" != "y" ]]; then + tuicAlgorithm= else - uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) + echoContent yellow "\nSource https://github.com/Loyalsoldier/v2ray-rules-dat" fi - elif [[ -z "${uuid}" ]]; then - uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) + elif [[ -n "${tuicAlgorithm}" && -n "${lastInstallationConfig}" ]]; then + echoContent yellow "The configuration file last installed for this protocol [${protocol}] was not read, and the first uuid of the configuration file was used" fi - if [[ -z "${uuid}" ]]; then - addClientsStatus= - echoContent red "\n ---> uuid reading error, regenerate" - uuid=$(/etc/v2ray-agent/v2ray/v2ctl uuid) - fi + if [[ -z "${tuicAlgorithm}" ]]; then - movePreviousConfig - # log - cat </etc/v2ray-agent/v2ray/conf/00_log.json + echoContent skyBlue "------------------------Version-------------------------------" + echoContent red "==============================================================" + echoContent yellow "\n ---> Port: ${hysteriaPort}" + 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 "Please enter the Hysteria port [enter random 10000-30000], cannot be repeated with other services" + fi +} + +#initTuicConfig() { +# +# 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 +#} + +addSingBoxRouteRule() { + local outboundTag=$1 + local domainList=$2 + local routingName=$3 + if [[ -f "${singBoxConfigPath}${routingName}.json" ]]; then + read -r -p "Previous configuration found. Keep it? [y/n]:" historyRouteStatus + if [[ "${historyRouteStatus}" == "y" ]]; then + domainList="${domainList},$(jq -rc .route.rules[0].rule_set[] "${singBoxConfigPath}${routingName}.json" | awk -F "[_]" '{print $1}' | paste -sd ',')" + domainList="${domainList},$(jq -rc .route.rules[0].domain_regex[] "${singBoxConfigPath}${routingName}.json" | awk -F "[*]" '{print $2}' | paste -sd ',' | sed 's/\\//g')" + fi + + fi + local rules= + rules=$(initSingBoxRules "${domainList}" "${routingName}") + local domainRules= + domainRules=$(echo "${rules}" | jq .domainRules) + + local ruleSet= + ruleSet=$(echo "${rules}" | jq .ruleSet) + + local ruleSetTag=[] + if [[ "$(echo "${ruleSet}" | jq '.|length')" != "0" ]]; then + ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)') + fi + if [[ -n "${singBoxConfigPath}" ]]; then + cat <"${singBoxConfigPath}${routingName}.json" { - "log": { - "error": "/etc/v2ray-agent/v2ray/error.log", - "loglevel": "warning" + "route": { + "rules": [ + { + "rule_set":${ruleSetTag}, + "domain_regex":${domainRules}, + "outbound": "${outboundTag}" + } + ], + "rule_set":${ruleSet} } } EOF - # outbounds - if [[ -n "${pingIPv6}" ]]; then - cat </etc/v2ray-agent/v2ray/conf/10_ipv6_outbounds.json + jq 'if .route.rule_set == [] then del(.route.rule_set) else . end' "${singBoxConfigPath}${routingName}.json" >"${singBoxConfigPath}${routingName}_tmp.json" && mv "${singBoxConfigPath}${routingName}_tmp.json" "${singBoxConfigPath}${routingName}.json" + fi + +} + +removeSingBoxRouteRule() { + local outboundTag=$1 + local delRules + if [[ -f "${singBoxConfigPath}${outboundTag}_route.json" ]]; then + delRules=$(jq -r 'del(.route.rules[]|select(.outbound=="'"${outboundTag}"'"))' "${singBoxConfigPath}${outboundTag}_route.json") + echo "${delRules}" >"${singBoxConfigPath}${outboundTag}_route.json" + fi +} + +addSingBoxOutbound() { + local tag=$1 + local type="ipv4" + local detour=$2 + if echo "${tag}" | grep -q "IPv6"; then + type=ipv6 + fi + if [[ -n "${detour}" ]]; then + cat <"${singBoxConfigPath}${tag}.json" { - "outbounds": [ + "outbounds": [ { - "protocol": "freedom", - "settings": {}, - "tag": "direct" + "type": "direct", + "tag": "${tag}", + "detour": "${detour}", + "domain_strategy": "${type}_only" } ] } EOF + elif echo "${tag}" | grep -q "direct"; then + cat <"${singBoxConfigPath}${tag}.json" +{ + "outbounds": [ + { + "type": "direct", + "tag": "${tag}" + } + ] +} +EOF + elif echo "${tag}" | grep -q "block"; then + + cat <"${singBoxConfigPath}${tag}.json" +{ + "outbounds": [ + { + "type": "block", + "tag": "${tag}" + } + ] +} +EOF else - cat </etc/v2ray-agent/v2ray/conf/10_ipv4_outbounds.json + cat <"${singBoxConfigPath}${tag}.json" +{ + "outbounds": [ + { + "type": "direct", + "tag": "${tag}", + "domain_strategy": "${type}_only" + } + ] +} +EOF + fi +} + +addXrayOutbound() { + local tag=$1 + local domainStrategy= + + if echo "${tag}" | grep -q "IPv4"; then + domainStrategy="ForceIPv4" + elif echo "${tag}" | grep -q "IPv6"; then + domainStrategy="ForceIPv6" + fi + + if [[ -n "${domainStrategy}" ]]; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.json" { "outbounds":[ { "protocol":"freedom", "settings":{ - "domainStrategy":"UseIPv4" + "domainStrategy":"${domainStrategy}" }, - "tag":"IPv4-out" - }, - { - "protocol":"freedom", - "settings":{ - "domainStrategy":"UseIPv6" - }, - "tag":"IPv6-out" - }, - { - "protocol":"blackhole", - "tag":"blackhole-out" + "tag":"${tag}" } ] } EOF fi - - # dns - cat </etc/v2ray-agent/v2ray/conf/11_dns.json + # direct + if echo "${tag}" | grep -q "direct"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.json" { - "dns": { - "servers": [ - "localhost" - ] - } + "outbounds":[ + { + "protocol":"freedom", + "settings": { + "domainStrategy":"UseIP" + }, + "tag":"${tag}" + } + ] } EOF - - # 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 - - 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 -{ -"inbounds":[ - { - "port": 31296, - "listen": "127.0.0.1", - "protocol": "trojan", - "tag":"trojanTCP", - "settings": { - "clients": [ - { - "password": "${uuid}", - "email": "default_Trojan_TCP" - } - ], - "fallbacks":[ - {"dest":"31300"} - ] - }, - "streamSettings": { - "network": "tcp", - "security": "none", - "tcpSettings": { - "acceptProxyProtocol": true - } - } - } - ] -} -EOF - addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_TCP_inbounds.json" "${addClientsStatus}" fi - - # VLESS_WS_TLS - if echo "${selectCustomInstallType}" | grep -q 1 || [[ "$1" == "all" ]]; then - fallbacksList=${fallbacksList}',{"path":"/'${customPath}'ws","dest":31297,"xver":1}' - getClients "${configPath}../tmp/03_VLESS_WS_inbounds.json" "${addClientsStatus}" - cat </etc/v2ray-agent/v2ray/conf/03_VLESS_WS_inbounds.json + # blackhole + if echo "${tag}" | grep -q "blackhole"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.json" { -"inbounds":[ + "outbounds":[ + { + "protocol":"blackhole", + "tag":"${tag}" + } + ] +} +EOF + fi + # socks5 outbound + if echo "${tag}" | grep -q "socks5"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.json" +{ + "outbounds": [ { - "port": 31297, - "listen": "127.0.0.1", - "protocol": "vless", - "tag":"VLESSWS", - "settings": { - "clients": [ - { - "id": "${uuid}", - "email": "default_VLESS_WS" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "acceptProxyProtocol": true, - "path": "/${customPath}ws" - } - } - } -] + "protocol": "socks", + "tag": "${tag}", + "settings": { + "servers": [ + { + "address": "${socks5RoutingOutboundIP}", + "port": ${socks5RoutingOutboundPort}, + "users": [ + { + "user": "${socks5RoutingOutboundUserName}", + "pass": "${socks5RoutingOutboundPassword}" + } + ] + } + ] + } + } + ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/03_VLESS_WS_inbounds.json" "${addClientsStatus}" fi + if echo "${tag}" | grep -q "wireguard_out_IPv4"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.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": "${tag}" + } + ] +} +EOF + fi + if echo "${tag}" | grep -q "wireguard_out_IPv6"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.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": "${tag}" + } + ] +} +EOF + fi + if echo "${tag}" | grep -q "vmess-out"; then + cat <"/etc/v2ray-agent/xray/conf/${tag}.json" +{ + "outbounds": [ + { + "tag": "${tag}", + "protocol": "vmess", + "streamSettings": { + "network": "ws", + "security": "tls", + "tlsSettings": {}, + "wsSettings": { + "path": "${setVMessWSTLSPath}" + } + }, + "mux": { + "enabled": true, + "concurrency": 8 + }, + "settings": { + "vnext": [ + { + "address": "${setVMessWSTLSAddress}", + "port": "${setVMessWSTLSPort}", + "users": [ + { + "id": "${setVMessWSTLSUUID}", + "security": "auto", + "alterId": 0 + } + ] + } + ] + } + } + ] +} +EOF + 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 +removeXrayOutbound() { + local tag=$1 + if [[ -f "/etc/v2ray-agent/xray/conf/${tag}.json" ]]; then + rm "/etc/v2ray-agent/xray/conf/${tag}.json" >/dev/null 2>&1 + fi +} +removeSingBoxConfig() { + + local tag=$1 + if [[ -f "${singBoxConfigPath}${tag}.json" ]]; then + rm "${singBoxConfigPath}${tag}.json" + fi +} + +addSingBoxWireGuardEndpoints() { + local type=$1 + + readConfigWarpReg + + cat <"${singBoxConfigPath}wireguard_endpoints_${type}.json" +{ + "endpoints": [ + { + "type": "wireguard", + "tag": "wireguard_endpoints_${type}", + "address": [ + "${address}" + ], + "private_key": "${secretKeyWarpReg}", + "peers": [ + { + "address": "162.159.192.1", + "port": 2408, + "public_key": "${publicKeyWarpReg}", + "reserved":${reservedWarpReg}, + "allowed_ips": ["0.0.0.0/0","::/0"] + } + ] + } + ] +} +EOF +} + +initSingBoxHysteria2Config() { + echoContent skyBlue "------------------------------------------------- ---------------" + + initHysteriaPort + initHysteria2Network + + cat </etc/v2ray-agent/sing-box/conf/config/hysteria2.json { "inbounds": [ { - "port": 31304, - "listen": "127.0.0.1", - "protocol": "trojan", - "tag": "trojangRPCTCP", - "settings": { - "clients": [ - { - "password": "${uuid}", - "email": "default_Trojan_gRPC" - } + "type": "hysteria2", + "listen": "::", + "listen_port": ${hysteriaPort}, + "users": $(initXrayClients 6), + "up_mbps":${hysteria2ClientDownloadSpeed}, + "down_mbps":${hysteria2ClientUploadSpeed}, + "tls": { + "enabled": true, + "server_name":"${currentHost}", + "alpn": [ + "h3" ], - "fallbacks": [ - { - "dest": "31300" - } - ] - }, - "streamSettings": { - "network": "grpc", - "grpcSettings": { - "serviceName": "${customPath}trojangrpc" - } + "certificate_path": "/etc/v2ray-agent/tls/${currentHost}.crt", + "key_path": "/etc/v2ray-agent/tls/${currentHost}.key" } } ] } EOF - addClients "/etc/v2ray-agent/v2ray/conf/04_trojan_gRPC_inbounds.json" "${addClientsStatus}" - fi - - # VMess_WS - if echo "${selectCustomInstallType}" | grep -q 3 || [[ "$1" == "all" ]]; then - fallbacksList=${fallbacksList}',{"path":"/'${customPath}'vws","dest":31299,"xver":1}' - - getClients "${configPath}../tmp/05_VMess_WS_inbounds.json" "${addClientsStatus}" - - cat </etc/v2ray-agent/v2ray/conf/05_VMess_WS_inbounds.json -{ -"inbounds":[ -{ - "listen": "127.0.0.1", - "port": 31299, - "protocol": "vmess", - "tag":"VMessWS", - "settings": { - "clients": [ - { - "id": "${uuid}", - "alterId": 0, - "add": "${add}", - "email": "default_VMess_WS" - } - ] - }, - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "acceptProxyProtocol": true, - "path": "/${customPath}vws" - } - } -} -] -} -EOF - 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 -{ - "inbounds":[ - { - "port": 31301, - "listen": "127.0.0.1", - "protocol": "vless", - "tag":"VLESSGRPC", - "settings": { - "clients": [ - { - "id": "${uuid}", - "add": "${add}", - "email": "default_VLESS_gRPC" - } - ], - "decryption": "none" - }, - "streamSettings": { - "network": "grpc", - "grpcSettings": { - "serviceName": "${customPath}grpc" - } - } - } -] -} -EOF - 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 - - cat </etc/v2ray-agent/v2ray/conf/02_VLESS_TCP_inbounds.json -{ -"inbounds":[ -{ - "port": ${defaultPort}, - "protocol": "vless", - "tag":"VLESSTCP", - "settings": { - "clients": [ - { - "id": "${uuid}", - "add":"${add}", - "email": "default_VLESS_TCP" - } - ], - "decryption": "none", - "fallbacks": [ - ${fallbacksList} - ] - }, - "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/v2ray/conf/02_VLESS_TCP_inbounds.json" "${addClientsStatus}" - } -# Initialize Xray Trojan XTLS configuration file -initXrayFrontingConfig() { - 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 +singBoxTuicInstall() { + if ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,"; then + echoContent red " ---> Port cannot be empty" 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 - - 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 - - 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"} - - 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"} - - echo "${VLESSConfig}" | jq . >${configPath}02_VLESS_TCP_inbounds.json - rm ${configPath}02_trojan_TCP_inbounds.json - fi - reloadCore - fi - - exit 0 + totalProgress=5 + installSingBox 1 + selectCustomInstallType=",9," + initSingBoxConfig custom 2 true + installSingBoxService 3 + reloadCore + showAccounts 4 } -# Move the last configuration file to a temporary file -movePreviousConfig() { +singBoxHysteria2Install() { + if ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,"; then + echoContent red " ---> The port is illegal" + exit 0 + 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 + totalProgress=5 + installSingBox 1 + selectCustomInstallType=",6," + initSingBoxConfig custom 2 true + installSingBoxService 3 + reloadCore + showAccounts 4 +} + +singBoxMergeConfig() { + rm /etc/v2ray-agent/sing-box/conf/config.json >/dev/null 2>&1 + /etc/v2ray-agent/sing-box/sing-box merge config.json -C /etc/v2ray-agent/sing-box/conf/config/ -D /etc/v2ray-agent/sing-box/conf/ >/dev/null 2>&1 +} + +#initXrayFrontingConfig() { +# if [[ -z "${configPath}" ]]; then +# menu +# exit 0 +# fi +# if [[ "${coreInstallType}" != "1" ]]; then +# fi +# local xtlsType= +# if echo ${currentInstallProtocolType} | grep -q trojan; then +# xtlsType=VLESS +# else +# xtlsType=Trojan +# fi +# +# echoContent red "\n==============================================================" +# +# echoContent red "==============================================================" +# if [[ "${selectType}" == "1" ]]; 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"} +# +# 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"} +# +# echo "${VLESSConfig}" | jq . >${configPath}02_VLESS_TCP_inbounds.json +# rm ${configPath}02_trojan_TCP_inbounds.json +# fi +# reloadCore +# fi +# +# exit 0 +#} + +initSingBoxPort() { + local port=$1 + if [[ -n "${port}" && -z "${lastInstallationConfig}" ]]; then + read -r -p "Previous port found. Use it? [y/n]:" historyPort + if [[ "${historyPort}" != "y" ]]; then + port= else - rm -rf "${configPath}../tmp/*" - mv ${configPath}[0][7-8]* ${configPath}../tmp/ 2>/dev/null - mv ${configPath}[0][2]* ${configPath}../tmp/ 2>/dev/null + echo "${port}" + fi + elif [[ -n "${port}" && -n "${lastInstallationConfig}" ]]; then + echo "${port}" + fi + if [[ -z "${port}" ]]; then + read -r -p 'Enter a custom port [must be valid and unique; Enter for random]:' port + if [[ -z "${port}" ]]; then + port=$((RANDOM % 50001 + 10000)) + fi + if ((port >= 1 && port <= 65535)); then + allowPort "${port}" + allowPort "${port}" "udp" + echo "${port}" + else + echoContent red "================================================== ===============" + exit 0 fi - fi } #Initialize Xray configuration file initXrayConfig() { - echoContent skyBlue "\nProgress$2/${totalProgress}: Initializing Xray configuration" + echoContent skyBlue "\nProgress$1/${totalProgress}: Xray version management" 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 [[ -n "${currentUUID}" && -z "${lastInstallationConfig}" ]]; 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 addClientsStatus=true - echoContent green "\n ---> Used successfully" + echoContent green " ---> V2Ray closed successfully" fi + elif [[ -n "${currentUUID}" && -n "${lastInstallationConfig}" ]]; then + addClientsStatus=true fi if [[ -z "${addClientsStatus}" ]]; then - echoContent yellow "Please enter custom UUID [need to be legal], [Enter] random UUID" + echoContent yellow "1.udp(QUIC)(default)" read -r -p 'UUID:' customUUID if [[ -n ${customUUID} ]]; then @@ -3421,19 +3788,26 @@ initXrayConfig() { uuid=$(/etc/v2ray-agent/xray/xray uuid) fi + echoContent yellow "2.faketcp" + read -r -p 'Username:' customEmail + if [[ -z ${customEmail} ]]; then + customEmail="$(echo "${uuid}" | cut -d "-" -f 1)-VLESS_TCP/TLS_Vision" + fi fi if [[ -z "${addClientsStatus}" && -z "${uuid}" ]]; then addClientsStatus= - echoContent red "\n ---> uuid reading error, randomly generated" + echoContent red "================================================== ===============" uuid=$(/etc/v2ray-agent/xray/xray uuid) fi if [[ -n "${uuid}" ]]; then - currentClients='[{"id":"'${uuid}'","add":"'${add}'","flow":"xtls-rprx-vision","email":"'${uuid}'-VLESS_TCP/TLS_Vision"}]' - echoContent yellow "\n ${uuid}" + currentClients='[{"id":"'${uuid}'","add":"'${add}'","flow":"xtls-rprx-vision","email":"'${customEmail}'"}]' + echoContent green "\n ${customEmail}:${uuid}" + echo fi + # log #log if [[ ! -f "/etc/v2ray-agent/xray/conf/00_log.json" ]]; then @@ -3441,7 +3815,8 @@ initXrayConfig() { { "log": { "error": "/etc/v2ray-agent/xray/error.log", - "loglevel": "warning" + "loglevel": "warning", + "dnsLog": false } } EOF @@ -3463,54 +3838,8 @@ EOF 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": [ - { - "protocol": "freedom", - "settings": {}, - "tag": "direct" - } - ] -} -EOF - - else - cat </etc/v2ray-agent/xray/conf/10_ipv4_outbounds.json -{ - "outbounds":[ - { - "protocol":"freedom", - "settings":{ - "domainStrategy":"UseIPv4" - }, - "tag":"IPv4-out" - }, - { - "protocol":"freedom", - "settings":{ - "domainStrategy":"UseIPv6" - }, - "tag":"IPv6-out" - }, - { - "protocol":"freedom", - "settings": {}, - "tag":"direct" - }, - { - "protocol":"blackhole", - "tag":"blackhole-out" - } - ] -} -EOF - fi - fi - + addXrayOutbound "z_direct_outbound" + # dns # dns if [[ ! -f "/etc/v2ray-agent/xray/conf/11_dns.json" ]]; then cat </etc/v2ray-agent/xray/conf/11_dns.json @@ -3524,8 +3853,7 @@ EOF EOF fi # routing - if [[ ! -f "/etc/v2ray-agent/xray/conf/09_routing.json" ]]; then - cat </etc/v2ray-agent/xray/conf/09_routing.json + cat </etc/v2ray-agent/xray/conf/09_routing.json { "routing": { "rules": [ @@ -3533,22 +3861,21 @@ EOF "type": "field", "domain": [ "domain:gstatic.com", - "domain:googleapis.com" + "domain:googleapis.com", + "domain:googleapis.cn" ], - "outboundTag": "direct" + "outboundTag": "z_direct_outbound" } ] } } EOF - fi # VLESS_TCP_TLS_Vision - # Fall back nginx - local fallbacksList='{"dest":31300,"xver":0},{"alpn":"h2","dest":31302,"xver":0}' + local fallbacksList='{"dest":31300,"xver":1},{"alpn":"h2","dest":31302,"xver":1}' # trojan - if echo "${selectCustomInstallType}" | grep -q 4 || [[ "$1" == "all" ]]; then - fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":0}' + if echo "${selectCustomInstallType}" | grep -q ",4," || [[ "$1" == "all" ]]; then + fallbacksList='{"dest":31296,"xver":1},{"alpn":"h2","dest":31302,"xver":1}' cat </etc/v2ray-agent/xray/conf/04_trojan_TCP_inbounds.json { "inbounds":[ @@ -3560,7 +3887,10 @@ EOF "settings": { "clients": $(initXrayClients 4), "fallbacks":[ - {"dest":"31300"} + { + "dest":"31300", + "xver":1 + } ] }, "streamSettings": { @@ -3569,17 +3899,17 @@ EOF "tcpSettings": { "acceptProxyProtocol": true } - } + } } ] } EOF - else + elif [[ -z "$3" ]]; then 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 + 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 { @@ -3605,103 +3935,119 @@ EOF ] } EOF - else + elif [[ -z "$3" ]]; then 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 - cat </etc/v2ray-agent/xray/conf/04_trojan_gRPC_inbounds.json + # VLESS_Reality_XHTTP_TLS + if echo "${selectCustomInstallType}" | grep -q ",12," || [[ "$1" == "all" ]]; then + initXrayXHTTPort + initRealityClientServersName + initRealityKey + initRealityMldsa65 + cat </etc/v2ray-agent/xray/conf/12_VLESS_XHTTP_inbounds.json { - "inbounds": [ +"inbounds":[ + { + "port": ${xHTTPort}, + "listen": "0.0.0.0", + "protocol": "vless", + "tag":"VLESSRealityXHTTP", + "settings": { + "clients": $(initXrayClients 12), + "decryption": "none" + }, + "streamSettings": { + "network": "xhttp", + "security": "reality", + "realitySettings": { + "show": false, + "target": "${realityServerName}:${realityDomainPort}", + "xver": 0, + "serverNames": [ + "${realityServerName}" + ], + "privateKey": "${realityPrivateKey}", + "publicKey": "${realityPublicKey}", + "mldsa65Seed": "${realityMldsa65Seed}", + "mldsa65Verify": "${realityMldsa65Verify}", + "minClientVer": "1.8.2", + "maxTimeDiff": 70000, + "shortIds": [ + "", + "6ba85179e30d4fc2" + ] + }, + "xhttpSettings": { + "host": "${realityServerName}", + "path": "/${customPath}xHTTP", + "mode": "auto" + } + } + } +] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/xray/conf/12_VLESS_XHTTP_inbounds.json >/dev/null 2>&1 + fi + 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":[ { - "port": 31304, - "listen": "127.0.0.1", - "protocol": "trojan", - "tag": "trojangRPCTCP", - "settings": { - "clients": $(initXrayClients 2), - "fallbacks": [ - { - "dest": "31300" - } - ] - }, - "streamSettings": { - "network": "grpc", - "grpcSettings": { - "serviceName": "${customPath}trojangrpc" - } + "listen": "127.0.0.1", + "port": 31299, + "protocol": "vmess", + "tag":"VMessWS", + "settings": { + "clients": $(initXrayClients 3) + }, + "streamSettings": { + "network": "ws", + "security": "none", + "wsSettings": { + "acceptProxyProtocol": true, + "path": "/${customPath}vws" } + } } ] } EOF - 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}' - cat </etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json -{ -"inbounds":[ -{ - "listen": "127.0.0.1", - "port": 31299, - "protocol": "vmess", - "tag":"VMessWS", - "settings": { - "clients": $(initXrayClients 3) - }, - "streamSettings": { - "network": "ws", - "security": "none", - "wsSettings": { - "acceptProxyProtocol": true, - "path": "/${customPath}vws" - } - } -} -] -} -EOF - else + elif [[ -z "$3" ]]; then rm /etc/v2ray-agent/xray/conf/05_VMess_WS_inbounds.json >/dev/null 2>&1 fi + # VLESS_gRPC + # if echo "${selectCustomInstallType}" | grep -q ",5," || [[ "$1" == "all" ]]; then + # cat </etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json + #{ + # "inbounds":[ + # { + # "port": 31301, + # "listen": "127.0.0.1", + # "protocol": "vless", + # "tag":"VLESSGRPC", + # "settings": { + # "clients": $(initXrayClients 5), + # "decryption": "none" + # }, + # "streamSettings": { + # "network": "grpc", + # "grpcSettings": { + # "serviceName": "${customPath}grpc" + # } + # } + # } + # ] + #} + #EOF + # elif [[ -z "$3" ]]; then + # rm /etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json >/dev/null 2>&1 + # fi - if echo "${selectCustomInstallType}" | grep -q 5 || [[ "$1" == "all" ]]; then - cat </etc/v2ray-agent/xray/conf/06_VLESS_gRPC_inbounds.json -{ - "inbounds":[ - { - "port": 31301, - "listen": "127.0.0.1", - "protocol": "vless", - "tag":"VLESSGRPC", - "settings": { - "clients": $(initXrayClients 5), - "decryption": "none" - }, - "streamSettings": { - "network": "grpc", - "grpcSettings": { - "serviceName": "${customPath}grpc" - } - } - } -] -} -EOF - 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 + if echo "${selectCustomInstallType}" | grep -q ",0," || [[ "$1" == "all" ]]; then cat </etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json { @@ -3722,17 +4068,13 @@ EOF "network": "tcp", "security": "tls", "tlsSettings": { + "rejectUnknownSni": true, "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" + "ocspStapling": 3600 } ] } @@ -3741,50 +4083,362 @@ EOF ] } EOF - else + elif [[ -z "$3" ]]; then rm /etc/v2ray-agent/xray/conf/02_VLESS_TCP_inbounds.json >/dev/null 2>&1 fi # VLESS_TCP/reality - if echo "${selectCustomInstallType}" | grep -q 7 || [[ "$1" == "all" ]]; then - echoContent skyBlue "\n===================== Configure VLESS+Reality ==================== =\n" - initRealityPort - initRealityDest + if echo "${selectCustomInstallType}" | grep -q ",7," || [[ "$1" == "all" ]]; then + echoContent skyBlue "------------------------Version-------------------------------" + + initXrayRealityPort initRealityClientServersName initRealityKey - + initRealityMldsa65 cat </etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json { "inbounds": [ { + "tag": "dokodemo-in-VLESSReality", "port": ${realityPort}, + "protocol": "dokodemo-door", + "settings": { + "address": "127.0.0.1", + "port": 45987, + "network": "tcp" + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "tls" + ], + "routeOnly": true + } + }, + { + "listen": "127.0.0.1", + "port": 45987, "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}", - "minClientVer": "1.8.2", - "maxTimeDiff": 70000, - "shortIds": [ + "show": false, + "target": "${realityServerName}:${realityDomainPort}", + "xver": 0, + "serverNames": [ + "${realityServerName}" + ], + "privateKey": "${realityPrivateKey}", + "publicKey": "${realityPublicKey}", + "mldsa65Seed": "${realityMldsa65Seed}", + "mldsa65Verify": "${realityMldsa65Verify}", + "minClientVer": "1.8.2", + "maxTimeDiff": 70000, + "shortIds": [ + "", + "6ba85179e30d4fc2" + ] + } + }, + "sniffing": { + "enabled": true, + "destOverride": [ + "http", + "tls", + "quic" + ], + "routeOnly": true + } + } + ], + "routing": { + "rules": [ + { + "inboundTag": [ + "dokodemo-in" + ], + "domain": [ + "${realityServerName}" + ], + "outboundTag": "z_direct_outbound" + }, + { + "inboundTag": [ + "dokodemo-in" + ], + "outboundTag": "blackhole_out" + } + ] + } +} +EOF + # cat </etc/v2ray-agent/xray/conf/08_VLESS_vision_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 + + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/xray/conf/07_VLESS_vision_reality_inbounds.json >/dev/null 2>&1 + rm /etc/v2ray-agent/xray/conf/08_VLESS_vision_gRPC_inbounds.json >/dev/null 2>&1 + fi + installSniffing + if [[ -z "$3" ]]; then + removeXrayOutbound wireguard_out_IPv4_route + removeXrayOutbound wireguard_out_IPv6_route + removeXrayOutbound wireguard_outbound + removeXrayOutbound IPv4_out + removeXrayOutbound IPv6_out + removeXrayOutbound socks5_outbound + removeXrayOutbound blackhole_out + removeXrayOutbound wireguard_out_IPv6 + removeXrayOutbound wireguard_out_IPv4 + addXrayOutbound z_direct_outbound + addXrayOutbound blackhole_out + fi +} + +initTCPBrutal() { + echoContent skyBlue "------------------------------------------------- ---------------" + read -r -p "Use TCP_Brutal? [y/n]:" tcpBrutalStatus + if [[ "${tcpBrutalStatus}" == "y" ]]; then + read -r -p "Enter local peak download speed (default: 100 Mbps):" tcpBrutalClientDownloadSpeed + if [[ -z "${tcpBrutalClientDownloadSpeed}" ]]; then + tcpBrutalClientDownloadSpeed=100 + fi + + read -r -p "Enter local peak upload speed (default: 50 Mbps):" tcpBrutalClientUploadSpeed + if [[ -z "${tcpBrutalClientUploadSpeed}" ]]; then + tcpBrutalClientUploadSpeed=50 + fi + fi +} +initSingBoxConfig() { + echoContent skyBlue "------------------------Version-------------------------------" + + echo + local uuid= + local addClientsStatus= + local sslDomain= + if [[ -n "${domain}" ]]; then + sslDomain="${domain}" + elif [[ -n "${currentHost}" ]]; then + sslDomain="${currentHost}" + fi + if [[ -n "${currentUUID}" && -z "${lastInstallationConfig}" ]]; 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 " ---> Hysteria started successfully" + fi + elif [[ -n "${currentUUID}" && -n "${lastInstallationConfig}" ]]; then + addClientsStatus=true + fi + + if [[ -z "${addClientsStatus}" ]]; then + echoContent yellow "3.wechat-video" + read -r -p 'UUID:' customUUID + + if [[ -n ${customUUID} ]]; then + uuid=${customUUID} + else + uuid=$(/etc/v2ray-agent/sing-box/sing-box generate uuid) + fi + + echoContent yellow "\n ---> Protocol: ${hysteriaProtocol}\n" + read -r -p 'Username:' customEmail + if [[ -z ${customEmail} ]]; then + customEmail="$(echo "${uuid}" | cut -d "-" -f 1)-VLESS_TCP/TLS_Vision" + fi + fi + + if [[ -z "${addClientsStatus}" && -z "${uuid}" ]]; then + addClientsStatus= + echoContent red " ---> Already added, cannot be added repeatedly, can be deleted and re-added" + uuid=$(/etc/v2ray-agent/sing-box/sing-box generate uuid) + fi + + if [[ -n "${uuid}" ]]; then + currentClients='[{"uuid":"'${uuid}'","flow":"xtls-rprx-vision","name":"'${customEmail}'"}]' + echoContent yellow "\n ${customEmail}:${uuid}" + fi + + # VLESS Vision + if echo "${selectCustomInstallType}" | grep -q ",0," || [[ "$1" == "all" ]]; then + echoContent yellow "Please enter the average delay from local to server, please fill it in according to the actual situation (default: 180, unit: ms)" + echoContent skyBlue "\nProgress$1/${totalProgress}: Verify service startup status" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVLESSVisionPort}") + echoContent green " ---> Hysteria closed successfully" + + checkDNSIP "${domain}" + removeNginxDefaultConf + handleSingBox stop + + checkPortOpen "${result[-1]}" "${domain}" + cat </etc/v2ray-agent/sing-box/conf/config/02_VLESS_TCP_inbounds.json +{ + "inbounds":[ + { + "type": "vless", + "listen":"::", + "listen_port":${result[-1]}, + "tag":"VLESSTCP", + "users":$(initSingBoxClients 0), + "tls":{ + "server_name": "${sslDomain}", + "enabled": true, + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/02_VLESS_TCP_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",1," || [[ "$1" == "all" ]]; then + echoContent yellow "\n ---> Delay: ${hysteriaLag}\n" + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure V2Ray to start automatically at boot" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVLESSWSPort}") + echoContent green " ---> Tuic started successfully" + + checkDNSIP "${domain}" + removeNginxDefaultConf + handleSingBox stop + randomPathFunction + checkPortOpen "${result[-1]}" "${domain}" + cat </etc/v2ray-agent/sing-box/conf/config/03_VLESS_WS_inbounds.json +{ + "inbounds":[ + { + "type": "vless", + "listen":"::", + "listen_port":${result[-1]}, + "tag":"VLESSWS", + "users":$(initSingBoxClients 1), + "tls":{ + "server_name": "${sslDomain}", + "enabled": true, + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + }, + "transport": { + "type": "ws", + "path": "/${currentPath}ws", + "max_early_data": 2048, + "early_data_header_name": "Sec-WebSocket-Protocol" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/03_VLESS_WS_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",3," || [[ "$1" == "all" ]]; then + echoContent yellow "Please enter the local bandwidth peak downstream speed (default: 100, unit: Mbps)" + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Hysteria to start automatically at boot" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVMessWSPort}") + echoContent green " ---> Tuic closed successfully" + + checkDNSIP "${domain}" + removeNginxDefaultConf + handleSingBox stop + randomPathFunction + checkPortOpen "${result[-1]}" "${domain}" + cat </etc/v2ray-agent/sing-box/conf/config/05_VMess_WS_inbounds.json +{ + "inbounds":[ + { + "type": "vmess", + "listen":"::", + "listen_port":${result[-1]}, + "tag":"VMessWS", + "users":$(initSingBoxClients 3), + "tls":{ + "server_name": "${sslDomain}", + "enabled": true, + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + }, + "transport": { + "type": "ws", + "path": "/${currentPath}", + "max_early_data": 2048, + "early_data_header_name": "Sec-WebSocket-Protocol" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/05_VMess_WS_inbounds.json >/dev/null 2>&1 + fi + + # VLESS_Reality_Vision + if echo "${selectCustomInstallType}" | grep -q ",7," || [[ "$1" == "all" ]]; then + echoContent yellow "\n --->Download speed: ${hysteriaClientDownloadSpeed}\n" + initRealityClientServersName + initRealityKey + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Tuic to start automatically at boot" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVLESSRealityVisionPort}") + echoContent green " ---> Xray started successfully" + cat </etc/v2ray-agent/sing-box/conf/config/07_VLESS_vision_reality_inbounds.json +{ + "inbounds": [ + { + "type": "vless", + "listen":"::", + "listen_port":${result[-1]}, + "tag": "VLESSReality", + "users":$(initSingBoxClients 7), + "tls": { + "enabled": true, + "server_name": "${realityServerName}", + "reality": { + "enabled": true, + "handshake":{ + "server": "${realityServerName}", + "server_port":${realityDomainPort} + }, + "private_key": "${realityPrivateKey}", + "short_id": [ + "", "6ba85179e30d4fc2" ] } @@ -3793,97 +4447,296 @@ EOF ] } EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/07_VLESS_vision_reality_inbounds.json >/dev/null 2>&1 + fi - cat </etc/v2ray-agent/xray/conf/08_VLESS_reality_fallback_grpc_inbounds.json + if echo "${selectCustomInstallType}" | grep -q ",8," || [[ "$1" == "all" ]]; then + echoContent yellow "Please enter the local bandwidth peak uplink speed (default: 50, unit: Mbps)" + initRealityClientServersName + initRealityKey + echoContent skyBlue "\nProgress$1/${totalProgress}: Configure Xray to start automatically at boot" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVLESSRealityGRPCPort}") + echoContent green " ---> Xray closed successfully" + cat </etc/v2ray-agent/sing-box/conf/config/08_VLESS_vision_gRPC_inbounds.json { "inbounds": [ { - "port": 31305, - "listen": "127.0.0.1", - "protocol": "vless", + "type": "vless", + "listen":"::", + "listen_port":${result[-1]}, + "users":$(initSingBoxClients 8), "tag": "VLESSRealityGRPC", - "settings": { - "clients": $(initXrayClients 8), - "decryption": "none" - }, - "streamSettings": { - "network": "grpc", - "grpcSettings": { - "serviceName": "grpc", - "multiMode": true + "tls": { + "enabled": true, + "server_name": "${realityServerName}", + "reality": { + "enabled": true, + "handshake":{ + "server":"${realityServerName}", + "server_port":${realityDomainPort} }, - "sockopt": { - "acceptProxyProtocol": true - } + "private_key": "${realityPrivateKey}", + "short_id": [ + "", + "6ba85179e30d4fc2" + ] + } + }, + "transport": { + "type": "grpc", + "service_name": "grpc" } } ] } 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 + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/08_VLESS_vision_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://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 + if echo "${selectCustomInstallType}" | grep -q ",6," || [[ "$1" == "all" ]]; then + echoContent yellow "\n ---> Upload speed: ${hysteriaClientUploadSpeed}\n" + echoContent skyBlue "\nPlease select the protocol type" + echo + mapfile -t result < <(initSingBoxPort "${singBoxHysteria2Port}") + echoContent green "\nPort range: ${hysteriaPortHoppingRange}\n" + initHysteria2Network + cat </etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json +{ + "inbounds": [ + { + "type": "hysteria2", + "listen": "::", + "listen_port": ${result[-1]}, + "users": $(initSingBoxClients 6), + "up_mbps":${hysteria2ClientDownloadSpeed}, + "down_mbps":${hysteria2ClientUploadSpeed}, + "tls": { + "enabled": true, + "server_name":"${sslDomain}", + "alpn": [ + "h3" + ], + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",4," || [[ "$1" == "all" ]]; then + echoContent yellow "# Notes\n" + echoContent skyBlue "\nProgress 1/1: Port jump" + echo + mapfile -t result < <(initSingBoxPort "${singBoxTrojanPort}") + echoContent green " ---> Port hopping added successfully" + cat </etc/v2ray-agent/sing-box/conf/config/04_trojan_TCP_inbounds.json +{ + "inbounds": [ + { + "type": "trojan", + "listen": "::", + "listen_port": ${result[-1]}, + "users": $(initSingBoxClients 4), + "tls": { + "enabled": true, + "server_name":"${sslDomain}", + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/04_trojan_TCP_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",9," || [[ "$1" == "all" ]]; then + echoContent yellow "Only supports UDP" + echoContent skyBlue "\nProgress 1/1: Port jump" + echo + mapfile -t result < <(initSingBoxPort "${singBoxTuicPort}") + echoContent green " ---> Deletion successful" + initTuicProtocol + cat </etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json +{ + "inbounds": [ + { + "type": "tuic", + "listen": "::", + "tag": "singbox-tuic-in", + "listen_port": ${result[-1]}, + "users": $(initSingBoxClients 9), + "congestion_control": "${tuicAlgorithm}", + "tls": { + "enabled": true, + "server_name":"${sslDomain}", + "alpn": [ + "h3" + ], + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",10," || [[ "$1" == "all" ]]; then + echoContent yellow "The starting position of port jumping is 30000" + echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Hysteria configuration" + echo + mapfile -t result < <(initSingBoxPort "${singBoxNaivePort}") + echoContent green " ---> The current port hopping range is: ${portHoppingStart}-${portHoppingEnd}" + cat </etc/v2ray-agent/sing-box/conf/config/10_naive_inbounds.json +{ + "inbounds": [ + { + "type": "naive", + "listen": "::", + "tag": "singbox-naive-in", + "listen_port": ${result[-1]}, + "users": $(initSingBoxClients 10), + "tls": { + "enabled": true, + "server_name":"${sslDomain}", + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/10_naive_inbounds.json >/dev/null 2>&1 + fi + if echo "${selectCustomInstallType}" | grep -q ",11," || [[ "$1" == "all" ]]; then + echoContent yellow "The end position of port jumping is 60000" + echoContent skyBlue "\nPlease select the algorithm type" + echo + mapfile -t result < <(initSingBoxPort "${singBoxVMessHTTPUpgradePort}") + echoContent green "\n ---> Port: ${tuicPort}" + + checkDNSIP "${domain}" + removeNginxDefaultConf + handleSingBox stop + randomPathFunction + rm -rf "${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf" >/dev/null 2>&1 + checkPortOpen "${result[-1]}" "${domain}" + singBoxNginxConfig "$1" "${result[-1]}" + bootStartup nginx + cat </etc/v2ray-agent/sing-box/conf/config/11_VMess_HTTPUpgrade_inbounds.json +{ + "inbounds":[ + { + "type": "vmess", + "listen":"127.0.0.1", + "listen_port":31306, + "tag":"VMessHTTPUpgrade", + "users":$(initSingBoxClients 11), + "transport": { + "type": "httpupgrade", + "path": "/${currentPath}" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/11_VMess_HTTPUpgrade_inbounds.json >/dev/null 2>&1 + fi + + if echo "${selectCustomInstallType}" | grep -q ",13," || [[ "$1" == "all" ]]; then + echoContent yellow "You can choose a segment in the range of 30000-60000" + echoContent skyBlue "\nProgress$1/${totalProgress}: Initializing Tuic configuration" + echo + mapfile -t result < <(initSingBoxPort "${singBoxAnyTLSPort}") + echoContent green "\n ---> Used successfully" + cat </etc/v2ray-agent/sing-box/conf/config/13_anytls_inbounds.json +{ + "inbounds": [ + { + "type": "anytls", + "listen": "::", + "tag":"anytls", + "listen_port": ${result[-1]}, + "users": $(initSingBoxClients 13), + "tls": { + "enabled": true, + "server_name":"${sslDomain}", + "certificate_path": "/etc/v2ray-agent/tls/${sslDomain}.crt", + "key_path": "/etc/v2ray-agent/tls/${sslDomain}.key" + } + } + ] +} +EOF + elif [[ -z "$3" ]]; then + rm /etc/v2ray-agent/sing-box/conf/config/13_anytls_inbounds.json >/dev/null 2>&1 + fi + + if [[ -z "$3" ]]; then + removeSingBoxConfig wireguard_endpoints_IPv4_route + removeSingBoxConfig wireguard_endpoints_IPv6_route + removeSingBoxConfig wireguard_endpoints_IPv4 + removeSingBoxConfig wireguard_endpoints_IPv6 + + removeSingBoxConfig IPv4_out + removeSingBoxConfig IPv6_out + removeSingBoxConfig IPv6_route + removeSingBoxConfig block + removeSingBoxConfig cn_block_outbound + removeSingBoxConfig cn_block_route + removeSingBoxConfig 01_direct_outbound + removeSingBoxConfig socks5_outbound.json + removeSingBoxConfig block_domain_outbound + removeSingBoxConfig dns + fi + + setSniffRouting +} +initSubscribeLocalConfig() { + rm -rf /etc/v2ray-agent/subscribe_local/sing-box/* } # General defaultBase64Code() { local type=$1 - local email=$2 - local id=$3 - local add=$4 + local port=$2 + local email=$3 + local id=$4 + local add=$5 + local path=$6 local user= user=$(echo "${email}" | awk -F "[-]" '{print $1}') - port=${currentDefaultPort} - + if [[ ! -f "/etc/v2ray-agent/subscribe_local/sing-box/${user}" ]]; then + echo [] >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + fi + local singBoxSubscribeLocalConfig= 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" + echoContent yellow "Recommend about 1000" + echoContent green " vless://${id}@${currentHost}:${port}?encryption=none&security=tls&fp=chrome&type=tcp&host=${currentHost}&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${email}\n" - 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} + echoContent yellow "Please enter the port jumping range, for example [30000-31000]" + 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" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${currentHost}:${port}?encryption=none&security=tls&type=tcp&host=${currentHost}&fp=chrome&headerType=none&sni=${currentHost}&flow=xtls-rprx-vision#${email} EOF - cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: vless server: ${currentHost} - port: ${currentDefaultPort} + port: ${port} uuid: ${id} network: tcp tls: true @@ -3891,43 +4744,21 @@ EOF flow: xtls-rprx-vision client-fingerprint: chrome EOF - 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" + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"${currentHost}\",\"server_port\":${port},\"uuid\":\"${id}\",\"flow\":\"xtls-rprx-vision\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"xudp\"}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" - 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" - - 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%26fp%3Dchrome%26host%3d${currentHost}%26headerType%3dnone%26type%3dtcp%23${email}\n" - fi - - 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 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_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 yellow "1.Add port hopping" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${port}%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 [[ "${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=$(echo -n "{\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"ws\",\"add\":\"${add}\",\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0) qrCodeBase64Default="${qrCodeBase64Default// /}" - 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 yellow "2.Delete port hopping" + echoContent green " {\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"ws\",\"add\":\"${add}\",\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n" + echoContent yellow "3.Check port jumping" echoContent green " vmess://${qrCodeBase64Default}\n" - echoContent yellow " ---> QR code vmess(VMess+WS+TLS)" + echoContent yellow "\n ---> Port: ${tuicPort}" cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" vmess://${qrCodeBase64Default} @@ -3936,7 +4767,7 @@ EOF - name: "${email}" type: vmess server: ${add} - port: ${currentDefaultPort} + port: ${port} uuid: ${id} alterId: 0 cipher: none @@ -3946,28 +4777,32 @@ EOF servername: ${currentHost} network: ws ws-opts: - path: /${currentPath}vws + path: ${path} headers: Host: ${currentHost} EOF + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vmess\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"alter_id\":0,\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"packetaddr\",\"transport\":{\"type\":\"ws\",\"path\":\"${path}\",\"max_early_data\":2048,\"early_data_header_name\":\"Sec-WebSocket-Protocol\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" 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 "Please enter the Tuic port [enter random 10000-30000], cannot be repeated with other services" + echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=${path}#${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 "1.bbr(default)" + 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}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=/${currentPath}ws#${email} +vless://${id}@${add}:${port}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=${path}#${email} EOF cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: vless server: ${add} - port: ${currentDefaultPort} + port: ${port} uuid: ${id} udp: true tls: true @@ -3975,30 +4810,77 @@ EOF client-fingerprint: chrome servername: ${currentHost} ws-opts: - path: /${currentPath}ws + path: ${path} 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${add}%3A${currentDefaultPort}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${currentHost}%26fp%3Dchrome%26sni%3D${currentHost}%26path%3D%252f${currentPath}ws%23${email}" + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"multiplex\":{\"enabled\":false,\"protocol\":\"smux\",\"max_streams\":32},\"packet_encoding\":\"xudp\",\"transport\":{\"type\":\"ws\",\"path\":\"${path}\",\"headers\":{\"Host\":\"${currentHost}\"}}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" - elif [[ "${type}" == "vlessgrpc" ]]; then + echoContent yellow "2.cubic" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dws%26host%3D${currentHost}%26fp%3Dchrome%26sni%3D${currentHost}%26path%3D${path}%23${email}" - 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" + elif [[ "${type}" == "vlessXHTTP" ]]; then - 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" + local xhttpMldsa65Param= + local xhttpMldsa65ParamEncoded= + if [[ -n "${currentRealityMldsa65Verify}" && "${currentRealityMldsa65Verify}" != "null" ]]; then + xhttpMldsa65Param="&pqv=${currentRealityMldsa65Verify}" + xhttpMldsa65ParamEncoded="%26pqv%3D${currentRealityMldsa65Verify}" + fi + + echoContent yellow "3.new_reno" + echoContent green " vless://${id}@${add}:${port}?encryption=none&security=reality${xhttpMldsa65Param}&type=xhttp&sni=${xrayVLESSRealityXHTTPServerName}&host=${xrayVLESSRealityXHTTPServerName}&fp=chrome&path=${path}&pbk=${currentRealityXHTTPPublicKey}&sid=6ba85179e30d4fc2#${email}\n" + + echoContent yellow "\n ---> Algorithm: ${tuicAlgorithm}\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${currentHost}%3A${currentDefaultPort}%3Fencryption%3Dnone%26fp%3Dchrome%26security%3Dtls%26type%3Dtcp%26${currentHost}%3D${currentHost}%26headerType%3Dnone%26sni%3D${currentHost}%26flow%3Dxtls-rprx-vision%23${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +vless://${id}@${add}:${port}?encryption=none&security=reality${xhttpMldsa65Param}&type=xhttp&sni=${xrayVLESSRealityXHTTPServerName}&fp=chrome&path=${path}&pbk=${currentRealityXHTTPPublicKey}&sid=6ba85179e30d4fc2#${email} +EOF + + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vless + server: ${add} + port: ${port} + uuid: ${id} + udp: true + tls: true + network: xhttp + client-fingerprint: chrome + alpn: + - h2 + servername: ${xrayVLESSRealityXHTTPServerName} + xhttp-opts: + path: ${path} + host: ${xrayVLESSRealityXHTTPServerName} + reality-opts: + public-key: ${currentRealityXHTTPPublicKey} + short-id: 6ba85179e30d4fc2 +EOF + + echoContent yellow "# Notes\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dreality${xhttpMldsa65ParamEncoded}%26type%3Dxhttp%26sni%3D${xrayVLESSRealityXHTTPServerName}%26fp%3Dchrome%26path%3D${path}%26host%3D${xrayVLESSRealityXHTTPServerName}%26pbk%3D${currentRealityXHTTPPublicKey}%26sid%3D6ba85179e30d4fc2%23${email}\n" + + elif + [[ "${type}" == "vlessgrpc" ]] + then + + echoContent yellow "will replace the prefix with ${xtlsType}" + echoContent green " vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&fp=chrome&serviceName=${currentPath}grpc&alpn=h2&sni=${currentHost}#${email}\n" + + 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 green " vless://${id}@${currentHost}:${currentDefaultPort}?security=tls&encryption=none&host=${currentHost}&fp=chrome&headerType=none&type=tcp#${email}\n" 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} +vless://${id}@${add}:${port}?encryption=none&security=tls&type=grpc&host=${currentHost}&path=${currentPath}grpc&serviceName=${currentPath}grpc&fp=chrome&alpn=h2&sni=${currentHost}#${email} EOF cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: vless server: ${add} - port: ${currentDefaultPort} + port: ${port} uuid: ${id} udp: true tls: true @@ -4008,43 +4890,53 @@ EOF grpc-opts: grpc-service-name: ${currentPath}grpc EOF - echoContent yellow " ---> QR code VLESS(VLESS+gRPC+TLS)" - echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${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}" + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\": \"vless\",\"server\": \"${add}\",\"server_port\": ${port},\"uuid\": \"${id}\",\"tls\": { \"enabled\": true, \"server_name\": \"${currentHost}\", \"utls\": { \"enabled\": true, \"fingerprint\": \"chrome\" }},\"packet_encoding\": \"xudp\",\"transport\": { \"type\": \"grpc\", \"service_name\": \"${currentPath}grpc\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "Execute again to switch to the last prefix\n" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40${add}%3A${port}%3Fencryption%3Dnone%26security%3Dtls%26type%3Dgrpc%26host%3D${currentHost}%26serviceName%3D${currentPath}grpc%26fp%3Dchrome%26path%3D${currentPath}grpc%26sni%3D${currentHost}%26alpn%3Dh2%23${email}" elif [[ "${type}" == "trojan" ]]; then + # URLEncode # 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 green " trojan://${id}@${currentHost}:${port}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n" cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" -trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${email}_Trojan +trojan://${id}@${currentHost}:${port}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${email}_Trojan EOF cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: trojan server: ${currentHost} - port: ${currentDefaultPort} + port: ${port} password: ${id} client-fingerprint: chrome udp: true sni: ${currentHost} EOF - echoContent yellow " ---> QR code Trojan(TLS)" + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"trojan\",\"server\":\"${currentHost}\",\"server_port\":${port},\"password\":\"${id}\",\"tls\":{\"alpn\":[\"http/1.1\"],\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "1.Switch to ${xtlsType}" 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 + # 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" + echoContent green " trojan://${id}@${add}:${port}?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} +trojan://${id}@${add}:${port}?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} + port: ${port} type: trojan password: ${id} network: grpc @@ -4053,184 +4945,250 @@ EOF 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" + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"trojan\",\"server\":\"${add}\",\"server_port\":${port},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"insecure\":true,\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"transport\":{\"type\":\"grpc\",\"service_name\":\"${currentPath}trojangrpc\",\"idle_timeout\":\"15s\",\"ping_timeout\":\"15s\",\"permit_without_stream\":false},\"multiplex\":{\"enabled\":false,\"protocol\":\"smux\",\"max_streams\":32}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "Please enter custom UUID [need to be legal], [Enter] random UUID" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=trojan%3a%2f%2f${id}%40${add}%3a${port}%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}" + local clashMetaPortContent="port: ${port}" + local multiPort= + local multiPortEncode + if echo "${port}" | grep -q "-"; then + clashMetaPortContent="ports: ${port}" + multiPort="mport=${port}&" + multiPortEncode="mport%3D${port}%26" fi - echoContent green " hysteria://${currentHost}:${hysteriaPort}?${mport}protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${hysteriaEmail}\n" + + echoContent green " hysteria2://${id}@${currentHost}:${singBoxHysteria2Port}?${multiPort}peer=${currentHost}&insecure=0&sni=${currentHost}&alpn=h3#${email}\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} +hysteria2://${id}@${currentHost}:${singBoxHysteria2Port}?${multiPort}peer=${currentHost}&insecure=0&sni=${currentHost}&alpn=h3#${email} 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" + echo "{\"server\": \"${currentHost}:${port}\",\"socks5\": { \"listen\": \"127.0.0.1:7798\", \"timeout\": 300},\"auth\":\"${id}\",\"tls\":{\"sni\":\"${currentHost}\"}}" | jq cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - - name: "${hysteriaEmail}" - type: hysteria + - name: "${email}" + type: hysteria2 server: ${currentHost} - ${clashMetaPortTmp} - auth_str: ${id} + ${clashMetaPortContent} + password: ${id} alpn: - - h3 - protocol: ${hysteriaProtocol} - up: "${hysteriaClientUploadSpeed}" - down: "${hysteriaClientDownloadSpeed}" + - h3 sni: ${currentHost} + up: "${hysteria2ClientUploadSpeed} Mbps" + down: "${hysteria2ClientDownloadSpeed} Mbps" 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" + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"hysteria2\",\"server\":\"${currentHost}\",\"server_port\":${singBoxHysteria2Port},\"up_mbps\":${hysteria2ClientUploadSpeed},\"down_mbps\":${hysteria2ClientDownloadSpeed},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"alpn\":[\"h3\"]}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "\n ${uuid}" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=hysteria2%3A%2F%2F${id}%40${currentHost}%3A${singBoxHysteria2Port}%3F${multiPortEncode}peer%3D${currentHost}%26insecure%3D0%26sni%3D${currentHost}%26alpn%3Dh3%23${email}\n" + + elif [[ "${type}" == "vlessReality" ]]; then + local realityServerName=${xrayVLESSRealityServerName} + local publicKey=${currentRealityPublicKey} + local realityMldsa65Verify=${currentRealityMldsa65Verify} + + if [[ "${coreInstallType}" == "2" ]]; then + realityServerName=${singBoxVLESSRealityVisionServerName} + publicKey=${singBoxVLESSRealityPublicKey} + fi + echoContent yellow "# Notes" + echoContent green " vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=tcp&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email}\n" + + echoContent yellow "\nTutorial address:" + echoContent green "Protocol type: VLESS, address: ${currentHost}, port: ${currentDefaultPort}, user ID: ${id}, security: tls, client-fingerprint: chrome, 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} +vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=tcp&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&flow=xtls-rprx-vision#${email} EOF cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: vless server: $(getPublicIP) - port: ${currentRealityPort} + port: ${port} uuid: ${id} network: tcp tls: true udp: true flow: xtls-rprx-vision - servername: ${currentRealityServerNames} + servername: ${realityServerName} reality-opts: - public-key: ${currentRealityPublicKey} + public-key: ${publicKey} 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" + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"$(getPublicIP)\",\"server_port\":${port},\"uuid\":\"${id}\",\"flow\":\"xtls-rprx-vision\",\"tls\":{\"enabled\":true,\"server_name\":\"${realityServerName}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"},\"reality\":{\"enabled\":true,\"public_key\":\"${publicKey}\",\"short_id\":\"6ba85179e30d4fc2\"}},\"packet_encoding\":\"xudp\"}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "\n1.CNAME www.digitalocean.com" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${port}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dtcp%26sni%3D${realityServerName}%26fp%3Dchrome%26pbk%3D${publicKey}%26sid%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" + local realityServerName=${xrayVLESSRealityServerName} + local publicKey=${currentRealityPublicKey} + local realityMldsa65Verify=${currentRealityMldsa65Verify} - 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" + if [[ "${coreInstallType}" == "2" ]]; then + realityServerName=${singBoxVLESSRealityGRPCServerName} + publicKey=${singBoxVLESSRealityPublicKey} + fi + + echoContent yellow "2.CNAME who.int" + # pqv=${realityMldsa65Verify}& + echoContent green " vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&type=grpc&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email}\n" + + echoContent yellow "3.CNAME blog.hostmonit.com" + # pqv=${realityMldsa65Verify}, + 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" 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} +vless://${id}@$(getPublicIP):${port}?encryption=none&security=reality&pqv=${realityMldsa65Verify}&type=grpc&sni=${realityServerName}&fp=chrome&pbk=${publicKey}&sid=6ba85179e30d4fc2&path=grpc&serviceName=grpc#${email} EOF cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" - name: "${email}" type: vless server: $(getPublicIP) - port: ${currentRealityPort} + port: ${port} uuid: ${id} network: grpc tls: true udp: true - servername: ${currentRealityServerNames} + servername: ${realityServerName} reality-opts: - public-key: ${currentRealityPublicKey} + public-key: ${publicKey} 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" + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vless\",\"server\":\"$(getPublicIP)\",\"server_port\":${port},\"uuid\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${realityServerName}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"},\"reality\":{\"enabled\":true,\"public_key\":\"${publicKey}\",\"short_id\":\"6ba85179e30d4fc2\"}},\"packet_encoding\":\"xudp\",\"transport\":{\"type\":\"grpc\",\"service_name\":\"grpc\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow "\n ---> Not used" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vless%3A%2F%2F${id}%40$(getPublicIP)%3A${port}%3Fencryption%3Dnone%26security%3Dreality%26type%3Dgrpc%26sni%3D${realityServerName}%26fp%3Dchrome%26pbk%3D${publicKey}%26sid%3D6ba85179e30d4fc2%26path%3Dgrpc%26serviceName%3Dgrpc%23${email}\n" elif [[ "${type}" == "tuic" ]]; then + local tuicUUID= + tuicUUID=$(echo "${id}" | awk -F "[_]" '{print $1}') + + local tuicPassword= + tuicPassword=$(echo "${id}" | awk -F "[_]" '{print $2}') if [[ -z "${email}" ]]; then - echoContent red " ---> Failed to read configuration, please reinstall" + echoContent red "\n================================================ =================" 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 " ---> Universal format (VLESS+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 " ---> 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" -} + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +tuic://${tuicUUID}:${tuicPassword}@${currentHost}:${port}?congestion_control=${tuicAlgorithm}&alpn=h3&sni=${currentHost}&udp_relay_mode=quic&allow_insecure=0#${email} EOF - local v2rayNConf= - v2rayNConf="$(cat /etc/v2ray-agent/tuic/conf/v2rayN.json)" - echoContent green "${v2rayNConf}" + echoContent yellow " ---> v2rayN(Tuic+TLS)" + echo "{\"relay\": {\"server\": \"${currentHost}:${port}\",\"uuid\": \"${tuicUUID}\",\"password\": \"${tuicPassword}\",\"ip\": \"${currentHost}\",\"congestion_control\": \"${tuicAlgorithm}\",\"alpn\": [\"h3\"]},\"local\": {\"server\": \"127.0.0.1:7798\"},\"log_level\": \"warn\"}" | jq - cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${email}" - - name: "${email}_tuic" + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" server: ${currentHost} type: tuic - port: ${tuicPort} - uuid: ${id} - password: ${id} + port: ${port} + uuid: ${tuicUUID} + password: ${tuicPassword} 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 + sni: ${email} EOF + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\": \"tuic\",\"server\": \"${currentHost}\",\"server_port\": ${port},\"uuid\": \"${tuicUUID}\",\"password\": \"${tuicPassword}\",\"congestion_control\": \"${tuicAlgorithm}\",\"tls\": {\"enabled\": true,\"server_name\": \"${currentHost}\",\"alpn\": [\"h3\"]}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow " ---> Formatted plain text (VLESS+TCP+TLS_Vision)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=tuic%3A%2F%2F${tuicUUID}%3A${tuicPassword}%40${currentHost}%3A${tuicPort}%3Fcongestion_control%3D${tuicAlgorithm}%26alpn%3Dh3%26sni%3D${currentHost}%26udp_relay_mode%3Dquic%26allow_insecure%3D0%23${email}\n" + elif [[ "${type}" == "naive" ]]; then + echoContent yellow " ---> Naive(TLS)" + + echoContent green " naive+https://${email}:${id}@${currentHost}:${port}?padding=true#${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +naive+https://${email}:${id}@${currentHost}:${port}?padding=true#${email} +EOF + echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS_Vision)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=naive%2Bhttps%3A%2F%2F${email}%3A${id}%40${currentHost}%3A${port}%3Fpadding%3Dtrue%23${email}\n" + elif [[ "${type}" == "vmessHTTPUpgrade" ]]; then + qrCodeBase64Default=$(echo -n "{\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"httpupgrade\",\"add\":\"${add}\",\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}" | base64 -w 0) + qrCodeBase64Default="${qrCodeBase64Default// /}" + + echoContent yellow " ---> Universal format (VLESS+TCP+TLS)" + echoContent green " {\"port\":${port},\"ps\":\"${email}\",\"tls\":\"tls\",\"id\":\"${id}\",\"aid\":0,\"v\":2,\"host\":\"${currentHost}\",\"type\":\"none\",\"path\":\"${path}\",\"net\":\"httpupgrade\",\"add\":\"${add}\",\"method\":\"none\",\"peer\":\"${currentHost}\",\"sni\":\"${currentHost}\"}\n" + echoContent yellow " ---> Formatted plain text (VLESS+TCP+TLS)" + echoContent green " vmess://${qrCodeBase64Default}\n" + echoContent yellow " ---> QR code VLESS(VLESS+TCP+TLS)" + + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" + vmess://${qrCodeBase64Default} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: vmess + server: ${add} + port: ${port} + uuid: ${id} + alterId: 0 + cipher: auto + udp: true + tls: true + client-fingerprint: chrome + servername: ${currentHost} + network: ws + ws-opts: + path: ${path} + headers: + Host: ${currentHost} + v2ray-http-upgrade: true +EOF + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"vmess\",\"server\":\"${add}\",\"server_port\":${port},\"uuid\":\"${id}\",\"security\":\"auto\",\"alter_id\":0,\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\",\"utls\":{\"enabled\":true,\"fingerprint\":\"chrome\"}},\"packet_encoding\":\"packetaddr\",\"transport\":{\"type\":\"httpupgrade\",\"path\":\"${path}\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" + + elif [[ "${type}" == "anytls" ]]; then + echoContent yellow " ---> AnyTLS" + + echoContent yellow " ---> Common format (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" + + echoContent green " anytls://${id}@${currentHost}:${singBoxAnyTLSPort}?peer=${currentHost}&insecure=0&sni=${currentHost}#${email}\n" + cat <>"/etc/v2ray-agent/subscribe_local/default/${user}" +anytls://${id}@${currentHost}:${singBoxAnyTLSPort}?peer=${currentHost}&insecure=0&sni=${currentHost}#${email} +EOF + cat <>"/etc/v2ray-agent/subscribe_local/clashMeta/${user}" + - name: "${email}" + type: anytls + port: ${singBoxAnyTLSPort} + server: ${currentHost} + password: ${id} + client-fingerprint: chrome + udp: true + sni: ${currentHost} + alpn: + - h2 + - http/1.1 +EOF + + singBoxSubscribeLocalConfig=$(jq -r ". += [{\"tag\":\"${email}\",\"type\":\"anytls\",\"server\":\"${currentHost}\",\"server_port\":${singBoxAnyTLSPort},\"password\":\"${id}\",\"tls\":{\"enabled\":true,\"server_name\":\"${currentHost}\"}}]" "/etc/v2ray-agent/subscribe_local/sing-box/${user}") + echo "${singBoxSubscribeLocalConfig}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${user}" + + echoContent yellow " ---> Formatted plain text (Trojan+TCP+TLS_Vision)" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=anytls%3A%2F%2F${id}%40${currentHost}%3A${singBoxAnyTLSPort}%3Fpeer%3D${currentHost}%26insecure%3D0%26sni%3D${currentHost}%23${email}\n" fi } @@ -4240,210 +5198,273 @@ showAccounts() { readInstallType readInstallProtocolType readConfigHostPathUUID - readHysteriaConfig - readXrayCoreRealityConfig - readHysteriaPortHopping - readTuicConfig + readSingBoxConfig + echo - echoContent skyBlue "\nProgress$1/${totalProgress}: account" - local show + echoContent skyBlue "\nProgress$2/${totalProgress}: Initializing V2Ray configuration" + + initSubscribeLocalConfig # 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 + if echo ${currentInstallProtocolType} | grep -q ",0,"; then - 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 + echoContent skyBlue "\nFunction 1/${totalProgress}: Switch to ${xtlsType}" + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}02_VLESS_TCP_inbounds.json | jq -c '.[]' | while read -r user; do local email= - email=$(echo "${user}" | jq -r .email) + email=$(echo "${user}" | jq -r .email//.name) - echoContent skyBlue "\n --->Account:${email}" + echoContent skyBlue "\nProgress$2/${totalProgress}: Initializing Xray configuration" echo - defaultBase64Code vlesstcp "${email}" "$(echo "${user}" | jq -r .id)" + defaultBase64Code vlesstcp "${currentDefaultPort}${singBoxVLESSVisionPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)" done fi # VLESS WS - if echo ${currentInstallProtocolType} | grep -q 1; then - echoContent skyBlue "\n================================ VLESS WS TLS CDN ================================\n" + if echo ${currentInstallProtocolType} | grep -q ",1,"; then + echoContent skyBlue "\n===================== Configure VLESS+Reality ==================== =\n" - jq .inbounds[0].settings.clients ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}03_VLESS_WS_inbounds.json | jq -c '.[]' | while read -r user; do local email= - email=$(echo "${user}" | jq -r .email) + email=$(echo "${user}" | jq -r .email//.name) - echoContent skyBlue "\n --->Account:${email}" + local vlessWSPort=${currentDefaultPort} + if [[ "${coreInstallType}" == "2" ]]; then + vlessWSPort="${singBoxVLESSWSPort}" + fi echo local path="${currentPath}ws" + + if [[ ${coreInstallType} == "1" ]]; then + path="/${currentPath}ws" + elif [[ "${coreInstallType}" == "2" ]]; then + path="${singBoxVLESSWSPath}" + fi + local count= while read -r line; do + echoContent skyBlue "\nProgress$1/${totalProgress}: Add cloudflare custom CNAME" if [[ -n "${line}" ]]; then - defaultBase64Code vlessws "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}" + defaultBase64Code vlessws "${vlessWSPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}" + count=$((count + 1)) + echo + fi + done < <(echo "${currentCDNAddress}" | tr ',' '\n') + done + fi + # trojan grpc + if echo ${currentInstallProtocolType} | grep -q ",2,"; then + echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip" + 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) + local count= + while read -r line; do + echoContent skyBlue "----------------------------" + echo + if [[ -n "${line}" ]]; then + defaultBase64Code trojangrpc "${currentDefaultPort}" "${email}${count}" "$(echo "${user}" | jq -r .password)" "${line}" count=$((count + 1)) fi - done < <(echo "${currentAdd}" | tr ',' '\n') + done < <(echo "${currentCDNAddress}" | tr ',' '\n') done fi + # VMess WS + if echo ${currentInstallProtocolType} | grep -q ",3,"; then + echoContent skyBlue "\nProgress$1/${totalProgress}: account" + local path="${currentPath}vws" + if [[ ${coreInstallType} == "1" ]]; then + path="/${currentPath}vws" + elif [[ "${coreInstallType}" == "2" ]]; then + path="${singBoxVMessWSPath}" + fi + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}05_VMess_WS_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email//.name) - #VLESS grpc - if echo ${currentInstallProtocolType} | grep -q 5; then - echoContent skyBlue "\n=============================== VLESS gRPC TLS CDN ===============================\n" + local vmessPort=${currentDefaultPort} + if [[ "${coreInstallType}" == "2" ]]; then + vmessPort="${singBoxVMessWSPort}" + fi + + local count= + while read -r line; do + echoContent skyBlue "===================== Trojan TCP TLS_Vision ======================\n" + echo + if [[ -n "${line}" ]]; then + defaultBase64Code vmessws "${vmessPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}" + count=$((count + 1)) + fi + done < <(echo "${currentCDNAddress}" | tr ',' '\n') + done + fi + + # trojan tcp + if echo ${currentInstallProtocolType} | grep -q ",4,"; then + echoContent skyBlue "\n --->Account:${email}" + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}04_trojan_TCP_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email//.name) + echoContent skyBlue "============================= VLESS TCP TLS_Vision ==============================\n" + + defaultBase64Code trojan "${currentDefaultPort}${singBoxTrojanPort}" "${email}" "$(echo "${user}" | jq -r .password)" + done + fi + # VLESS grpc + if echo ${currentInstallProtocolType} | grep -q ",5,"; then + echoContent skyBlue "\n --->Account:${email}" 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) - 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') - - done - fi - - # 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) - - 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 - - #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}" - - defaultBase64Code trojan "${email}" "$(echo "${user}" | jq -r .password)" - done - fi - - 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) - - 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') - - 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" - - jq .auth.config ${hysteriaConfigPath}config.json | jq -r '.[]' | while read -r user; do - local defaultUser= - local uuidType= - uuidType=".id" - - if [[ "${frontingType}" == "02_trojan_TCP_inbounds" ]]; then - uuidType=".password" - fi - - defaultUser=$(jq '.inbounds[0].settings.clients[]|select('${uuidType}'=="'"${user}"'")' ${configPath}${frontingType}.json) - local email= - email=$(echo "${defaultUser}" | jq -r .email) - local hysteriaEmail= - hysteriaEmail=$(echo "${email}" | awk -F "[_]" '{print $1}')_hysteria - - if [[ -n ${defaultUser} ]]; then - echoContent skyBlue "\n ---> Account:$(echo "${hysteriaEmail}" | awk -F "[-]" '{print $1"_hysteria"}')" + echoContent skyBlue "\n================================ VLESS WS TLS CDN ================================\n" echo - defaultBase64Code hysteria "${hysteriaEmail}" "${user}" - fi + if [[ -n "${line}" ]]; then + defaultBase64Code vlessgrpc "${currentDefaultPort}" "${email}${count}" "$(echo "${user}" | jq -r .id)" "${line}" + count=$((count + 1)) + fi + done < <(echo "${currentCDNAddress}" | tr ',' '\n') done + fi + # hysteria2 + if echo ${currentInstallProtocolType} | grep -q ",6," || [[ -n "${hysteriaPort}" ]]; then + readPortHopping "hysteria2" "${singBoxHysteria2Port}" + echoContent skyBlue "\n --->Account:${email}" + local path="${configPath}" + if [[ "${coreInstallType}" == "1" ]]; then + path="${singBoxConfigPath}" + fi + local hysteria2DefaultPort= + if [[ -n "${hysteria2PortHoppingStart}" && -n "${hysteria2PortHoppingEnd}" ]]; then + hysteria2DefaultPort="${hysteria2PortHopping}" + else + hysteria2DefaultPort=${singBoxHysteria2Port} + fi + + jq -r -c '.inbounds[]|.users[]' "${path}06_hysteria2_inbounds.json" | while read -r user; do + echoContent skyBlue "\n ---> Account:$(echo "${user}" | jq -r .name)" + echo + defaultBase64Code hysteria "${hysteria2DefaultPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .password)" + 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 + if echo ${currentInstallProtocolType} | grep -q ",7,"; then + echoContent skyBlue "\n=============================== VLESS gRPC TLS CDN ===============================\n" + jq .inbounds[1].settings.clients//.inbounds[0].users ${configPath}07_VLESS_vision_reality_inbounds.json | jq -c '.[]' | while read -r user; do local email= - email=$(echo "${user}" | jq -r .email) + email=$(echo "${user}" | jq -r .email//.name) echoContent skyBlue "\n --->Account:${email}" echo - defaultBase64Code vlessReality "${email}" "$(echo "${user}" | jq -r .id)" + defaultBase64Code vlessReality "${xrayVLESSRealityVisionPort}${singBoxVLESSRealityVisionPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)" 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 + # VLESS reality gRPC + if echo ${currentInstallProtocolType} | grep -q ",8,"; then + echoContent skyBlue "\n================================ VMess WS TLS CDN ================================\n" + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}08_VLESS_vision_gRPC_inbounds.json | jq -c '.[]' | while read -r user; do local email= - email=$(echo "${user}" | jq -r .email) + email=$(echo "${user}" | jq -r .email//.name) echoContent skyBlue "\n --->Account:${email}" echo - defaultBase64Code vlessRealityGRPC "${email}" "$(echo "${user}" | jq -r .id)" + defaultBase64Code vlessRealityGRPC "${xrayVLESSRealityVisionPort}${singBoxVLESSRealityGRPCPort}" "${email}" "$(echo "${user}" | jq -r .id//.uuid)" 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." + # tuic + if echo ${currentInstallProtocolType} | grep -q ",9," || [[ -n "${tuicPort}" ]]; then + echoContent skyBlue "\n================================== Trojan TLS ==================================\n" + local path="${configPath}" + if [[ "${coreInstallType}" == "1" ]]; then + path="${singBoxConfigPath}" + fi + jq -r -c '.inbounds[].users[]' "${path}09_tuic_inbounds.json" | while read -r user; do + echoContent skyBlue "\n ---> Account:$(echo "${user}" | jq -r .name)" + echo + defaultBase64Code tuic "${singBoxTuicPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .uuid)_$(echo "${user}" | jq -r .password)" + done - 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}') + fi + # naive + if echo ${currentInstallProtocolType} | grep -q ",10," || [[ -n "${singBoxNaivePort}" ]]; then + echoContent skyBlue "\n --->Account:${email}" - if [[ -n ${tuicEmail} ]]; then - echoContent skyBlue "\n --->Account:${tuicEmail}_tuic" - echo - defaultBase64Code tuic "${tuicEmail}" "${id}" + jq -r -c '.inbounds[]|.users[]' "${configPath}10_naive_inbounds.json" | while read -r user; do + echoContent skyBlue "\n ---> Account:$(echo "${user}" | jq -r .username)" + echo + defaultBase64Code naive "${singBoxNaivePort}" "$(echo "${user}" | jq -r .username)" "$(echo "${user}" | jq -r .password)" + done + + fi + # VMess HTTPUpgrade + if echo ${currentInstallProtocolType} | grep -q ",11,"; then + echoContent skyBlue "\n================================ Trojan gRPC TLS ================================\n" + local path="${currentPath}vws" + if [[ ${coreInstallType} == "1" ]]; then + path="/${currentPath}vws" + elif [[ "${coreInstallType}" == "2" ]]; then + path="${singBoxVMessHTTPUpgradePath}" + fi + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}11_VMess_HTTPUpgrade_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email//.name) + + local vmessHTTPUpgradePort=${currentDefaultPort} + if [[ "${coreInstallType}" == "2" ]]; then + vmessHTTPUpgradePort="${singBoxVMessHTTPUpgradePort}" fi + local count= + while read -r line; do + echoContent skyBlue "\n --->Account:${email}" + echo + if [[ -n "${line}" ]]; then + defaultBase64Code vmessHTTPUpgrade "${vmessHTTPUpgradePort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}" + count=$((count + 1)) + fi + done < <(echo "${currentCDNAddress}" | tr ',' '\n') + done + fi + # VLESS Reality XHTTP + if echo ${currentInstallProtocolType} | grep -q ",12,"; then + echoContent skyBlue "\n================================ Hysteria TLS ================================\n" + + jq .inbounds[0].settings.clients//.inbounds[0].users ${configPath}12_VLESS_XHTTP_inbounds.json | jq -c '.[]' | while read -r user; do + local email= + email=$(echo "${user}" | jq -r .email//.name) + echo + local path="${currentPath}xHTTP" + + local count= + while read -r line; do + echoContent skyBlue "============================= VLESS reality_vision ==============================\n" + if [[ -z "${line}" ]]; then + line=$(getPublicIP) + fi + if [[ -n "${line}" ]]; then + defaultBase64Code vlessXHTTP "${xrayVLESSRealityXHTTPort}" "${email}${count}" "$(echo "${user}" | jq -r .id//.uuid)" "${line}" "${path}" + count=$((count + 1)) + echo + fi + done < <(echo "${currentCDNAddress}" | tr ',' '\n') + done + fi + # AnyTLS + if echo ${currentInstallProtocolType} | grep -q ",13,"; then + echoContent skyBlue "\n================================ AnyTLS ================================\n" + + jq -r -c '.inbounds[]|.users[]' "${configPath}13_anytls_inbounds.json" | while read -r user; do + echoContent skyBlue "\n ---> Account:$(echo "${user}" | jq -r .name)" + echo + defaultBase64Code anytls "${singBoxAnyTLSPort}" "$(echo "${user}" | jq -r .name)" "$(echo "${user}" | jq -r .password)" done fi - - if [[ -z ${show} ]]; then - echoContent red " ---> not installed" - fi } # Remove nginx302 configuration removeNginx302() { @@ -4465,14 +5486,14 @@ checkNginx302() { 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 + # local domain302Result= + # domain302Result=$(curl -L -s "https://${currentHost}:${currentPort}") + # if [[ -n "${domain302Result}" ]]; then + 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" + exit 0 + # fi fi - echoContent red " ---> 302 redirection setting failed, please double check whether it is the same as the example" + echoContent red " ---> Range cannot be empty" backupNginxConfig restoreBackup } @@ -4480,22 +5501,23 @@ checkNginx302() { backupNginxConfig() { if [[ "$1" == "backup" ]]; then cp ${nginxConfigPath}alone.conf /etc/v2ray-agent/alone_backup.conf - echoContent green " ---> nginx configuration file backup successful" + 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" 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" + echoContent green " vmess://${qrCodeBase64Default}\n" 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" <"${nginxConfigPath}alone.conf" | while read -r line; do + grep -n "location / {" <"${nginxConfigPath}alone.conf" | while read -r line; do if [[ -n "${line}" ]]; then local insertIndex= insertIndex="$(echo "${line}" | awk -F "[:]" '{print $1}')" @@ -4503,7 +5525,7 @@ addNginx302() { 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" + echoContent red " ---> The range is illegal" backupNginxConfig restoreBackup fi @@ -4512,34 +5534,43 @@ addNginx302() { # Update camouflage station updateNginxBlog() { - echoContent skyBlue "\nProgress$1/${totalProgress}: Change disguise site" - - 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" + if [[ "${coreInstallType}" == "2" ]]; then + echoContent red " ---> The range is illegal" 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 skyBlue "\n --->Account:${email}" + + if ! echo "${currentInstallProtocolType}" | grep -q ",0," || [[ -z "${coreInstallType}" ]]; then + echoContent red " ---> Failed to add port hopping" + exit 0 + fi + echoContent red "==============================================================" + echoContent yellow " ---> QR code Trojan(Trojan+TCP+TLS_Vision)" + echoContent yellow " ---> Universal json(VMess+WS+TLS)" + echoContent yellow " ---> Universal vmess (VMess+WS+TLS) link" + echoContent yellow " ---> QR code vmess(VMess+WS+TLS)" + echoContent yellow " ---> Universal format (VLESS+WS+TLS)" + echoContent yellow " ---> Formatted plain text (VLESS+WS+TLS)" 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 "================================================== ===============" + echoContent yellow " ---> QR code VLESS(VLESS+WS+TLS)" + echoContent yellow " ---> Universal format (VLESS+gRPC+TLS)" + echoContent yellow " ---> Formatted plain text (VLESS+gRPC+TLS)" + echoContent yellow " ---> QR code VLESS(VLESS+gRPC+TLS)" + echoContent red "==============================================================" read -r -p "Please select:" selectInstallNginxBlogType 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 "================================================== ===============" + if [[ "${coreInstallType}" == "2" ]]; then + echoContent red " ---> Unable to recognize iptables tool, unable to use port jump, exit installation" + exit 0 + fi + echoContent red "\n==============================================================" + echoContent yellow " ---> Trojan(TLS)" + echoContent yellow " ---> QR code Trojan(TLS)" + echoContent yellow " ---> Trojan gRPC(TLS)" + echoContent yellow " ---> QR code Trojan gRPC(TLS)" + echoContent red "==============================================================" read -r -p "Please select:" redirectStatus if [[ "${redirectStatus}" == "1" ]]; then @@ -4559,41 +5590,50 @@ updateNginxBlog() { fi if [[ "${redirectStatus}" == "2" ]]; then removeNginx302 - echoContent green " ---> Removed 302 redirect successfully" + echoContent green " https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=vmess://${qrCodeBase64Default}\n" exit 0 fi fi if [[ "${selectInstallNginxBlogType}" =~ ^[1-9]$ ]]; then - rm -rf "${nginxStaticPath}" + rm -rf "${nginxStaticPath}*" - wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" >/dev/null + if [[ "${release}" == "alpine" ]]; then + wget -q -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" + else + wget -q "${wgetShowProgressStatus}" -P "${nginxStaticPath}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/fodder/blog/unable/html${selectInstallNginxBlogType}.zip" + fi unzip -o "${nginxStaticPath}html${selectInstallNginxBlogType}.zip" -d "${nginxStaticPath}" >/dev/null rm -f "${nginxStaticPath}html${selectInstallNginxBlogType}.zip*" - echoContent green " ---> Pseudo site replaced successfully" + echoContent green " vless://${id}@${add}:${currentDefaultPort}?encryption=none&security=tls&type=ws&host=${currentHost}&sni=${currentHost}&fp=chrome&path=/${currentPath}ws #${email}\n" else - echoContent red " ---> Wrong selection, please select again" + echoContent red "\n================================================ =================" updateNginxBlog fi } #Add new port addCorePort() { - 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.Check the added port" - echoContent yellow "2.Add port" - echoContent yellow "3.Delete port" - echoContent red "================================================== ===============" + if [[ "${coreInstallType}" == "2" ]]; then + echoContent red " ---> Port cannot be empty" + exit 0 + fi + + echoContent skyBlue "============================== VLESS reality_gRPC ===============================\n" + echoContent red "\n==============================================================" + echoContent yellow " ---> Hysteria(TLS)" + echoContent yellow " ---> v2rayN(hysteria+TLS)" + echoContent yellow " ---> QR code Hysteria(TLS)" + echoContent yellow " ---> Universal format (VLESS+reality+uTLS+Vision)" + echoContent yellow " ---> Formatted plain text (VLESS+reality+uTLS+Vision)" + echoContent yellow " ---> QR code VLESS(VLESS+reality+uTLS+Vision)" + echoContent yellow " ---> Universal format (VLESS+reality+uTLS+gRPC)" + + echoContent yellow " ---> Formatted plain text (VLESS+reality+uTLS+gRPC)" + echoContent yellow " ---> QR code VLESS(VLESS+reality+uTLS+gRPC)" + echoContent yellow " ---> Formatted plain text (Tuic+TLS)" + 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}' @@ -4623,7 +5663,6 @@ addCorePort() { hysteriaFileName="${configPath}02_dokodemodoor_inbounds_hysteria_${port}.json" fi - # open port allowPort "${port}" allowPort "${port}" "udp" @@ -4672,7 +5711,7 @@ EOF EOF done < <(echo "${newPort}" | tr ',' '\n') - echoContent green " ---> Added successfully" + 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" reloadCore addCorePort fi @@ -4693,7 +5732,7 @@ EOF reloadCore addCorePort else - echoContent yellow "\n ---> The number entered is wrong, please choose again" + echoContent yellow " ---> v2rayN(Tuic+TLS)" addCorePort fi fi @@ -4703,39 +5742,40 @@ EOF unInstall() { 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" + 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}" menu exit 0 fi - echoContent yellow " ---> The script will not delete acme related configurations. To delete, please execute manually [rm -rf /root/.acme.sh]" + # checkBTPanel + echoContent yellow "\n --->Tuic will be warmer and may have a smoother user experience than Hysteria." handleNginx stop if [[ -z $(pgrep -f "nginx") ]]; then - echoContent green " ---> Stop Nginx successfully" + 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" 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" - - elif [[ "${coreInstallType}" == "2" ]]; then - - handleV2Ray stop - rm -rf /etc/systemd/system/v2ray.service - echoContent green " ---> Delete V2Ray 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 and it will start automatically after booting" - fi - - if [[ -z "${tuicConfigPath}" ]]; then - handleTuic stop - rm -rf /etc/systemd/system/tuic.service - echoContent green " ---> Delete Tuic and start automatically after booting" + if [[ "${release}" == "alpine" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + rc-update del xray default + rm -rf /etc/init.d/xray + 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" + fi + if [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then + handleSingBox stop + rc-update del sing-box default + rm -rf /etc/init.d/sing-box + 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}" + fi + else + if [[ "${coreInstallType}" == "1" ]]; then + handleXray stop + rm -rf /etc/systemd/system/xray.service + echoContent green " trojan://${id}@${currentHost}:${currentDefaultPort}?peer=${currentHost}&fp=chrome&sni=${currentHost}&alpn=http/1.1#${currentHost}_Trojan\n" + fi + if [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then + handleSingBox stop + rm -rf /etc/systemd/system/sing-box.service + 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" + fi fi # if [[ -f "/root/.acme.sh/acme.sh.env" ]] && grep -q 'acme.sh.env' /dev/null 2>&1 + rm -rf "${nginxConfigPath}sing_box_VMess_HTTPUpgrade.conf" >/dev/null 2>&1 + rm -rf ${nginxConfigPath}checkPortOpen.conf >/dev/null 2>&1 + + unInstallSubscribe if [[ -d "${nginxStaticPath}" && -f "${nginxStaticPath}/check" ]]; then rm -rf "${nginxStaticPath}" - echoContent green " ---> Deletion of fake website completed" + 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" fi rm -rf /usr/bin/vasma rm -rf /usr/sbin/vasma - echoContent green " ---> Uninstallation of shortcut completed" - echoContent green " ---> Uninstall v2ray-agent script completed" + 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" + echoContent green " hysteria://${currentHost}:${hysteriaPort}?${mport}protocol=${hysteriaProtocol}&auth=${id}&peer=${currentHost}&insecure=0&alpn=h3&upmbps=${hysteriaClientUploadSpeed}&downmbps=${hysteriaClientDownloadSpeed}#${hysteriaEmail}\n" } -# Modify V2Ray CDN node -updateV2RayCDN() { +manageCDN() { + echoContent skyBlue "\n --->Account:${email}" + local setCDNDomain= - echoContent skyBlue "\nProgress$1/${totalProgress}: Modify CDN node" + if echo "${currentInstallProtocolType}" | grep -qE ",1,|,2,|,3,|,5,|,11,"; then + echoContent red "==============================================================" + echoContent yellow "# If you need to customize, please manually copy the template file to ${nginxStaticPath} \n" + echoContent yellow "1.Newbie guide" + echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip" + echoContent red " ---> The port is illegal" - 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 "================================================== ===============" + echoContent yellow "4.CNAME www.visa.com.hk" + echoContent yellow "2.Game website" + echoContent yellow "3.Personal blog 01" + echoContent red "==============================================================" read -r -p "Please select:" selectCDNType case ${selectCDNType} in 1) - setDomain="www.digitalocean.com" + setCDNDomain="www.digitalocean.com" ;; 2) - setDomain="who.int" + setCDNDomain="who.int" ;; 3) - setDomain="blog.hostmonit.com" + setCDNDomain="blog.hostmonit.com" ;; 4) - read -r -p "Please enter the CDN IP or domain name you want to customize:" setDomain + setCDNDomain="www.visa.com.hk" ;; 5) - setDomain=${currentHost} + read -r -p "Enter the custom CDN IP or domain:" setCDNDomain + ;; + 6) + echo >/etc/v2ray-agent/cdn + echoContent green "${v2rayNConf}\n" + exit 0 ;; esac - 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" + if [[ -n "${setCDNDomain}" ]]; then + echo >/etc/v2ray-agent/cdn + echo "${setCDNDomain}" >"/etc/v2ray-agent/cdn" + 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" + subscribe false false + else + echoContent red "================================================== ===============" + manageCDN 1 fi else - echoContent red " ---> Available types are not installed" + echoContent yellow "4.Enterprise Station" + echoContent skyBlue "https://www.v2ray-agent.com/archives/cloudflarezi-xuan-ip\n" + echoContent red "================================================== =========== ====" fi } - -# 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 " ---> Wrong selection" - fi -} - # Custom uuid customUUID() { - read -r -p "Please enter a legal UUID, [Enter] random UUID:" currentCustomUUID + read -r -p "Please enter a valid UUID:" currentCustomUUID echo if [[ -z "${currentCustomUUID}" ]]; then - currentCustomUUID=$(${ctlPath} uuid) + if [[ "${selectInstallType}" == "1" || "${coreInstallType}" == "1" ]]; then + currentCustomUUID=$(${ctlPath} uuid) + elif [[ "${selectInstallType}" == "2" || "${coreInstallType}" == "2" ]]; then + currentCustomUUID=$(${ctlPath} generate uuid) + fi + 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 + local checkUUID= + if [[ "${coreInstallType}" == "1" ]]; then + checkUUID=$(jq -r --arg currentUUID "$currentCustomUUID" "(.inbounds[0].settings.clients // .inbounds[1].settings.clients)[]? | select(.id == \$currentUUID) | .email" ${configPath}${frontingType:-$frontingTypeReality}.json) + elif [[ "${coreInstallType}" == "2" ]]; then + checkUUID=$(jq -r --arg currentUUID "$currentCustomUUID" ".inbounds[0].users[] | select(.uuid == \$currentUUID) | .name//.username" ${configPath}${frontingType}.json) + fi + + if [[ -n "${checkUUID}" ]]; 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 fi @@ -4856,350 +5903,334 @@ customUserEmail() { currentCustomEmail="${currentCustomUUID}" echoContent yellow "email: ${currentCustomEmail}\n" else - local defaultConfig=${frontingType} + local checkEmail= + if [[ "${coreInstallType}" == "1" ]]; then + local frontingTypeConfig="${frontingType}" + if [[ "${currentInstallProtocolType}" == ",7,8," ]]; then + frontingTypeConfig="07_VLESS_vision_reality_inbounds" + fi - if echo "${currentInstallProtocolType}" | grep -q "7" && [[ -z "${frontingType}" ]]; then - defaultConfig="07_VLESS_vision_reality_inbounds" + checkEmail=$(jq -r --arg currentEmail "$currentCustomEmail" "(.inbounds[0].settings.clients // .inbounds[1].settings.clients)[]? | select(.email == \$currentEmail) | .email" ${configPath}${frontingTypeConfig:-$frontingTypeReality}.json) + elif + [[ "${coreInstallType}" == "2" ]] + then + checkEmail=$(jq -r --arg currentEmail "$currentCustomEmail" ".inbounds[0].users[] | select(.name == \$currentEmail) | .name" ${configPath}${frontingType}.json) 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 + if [[ -n "${checkEmail}" ]]; then + echoContent red "\n ---> uuid reading error, regenerate" exit 0 fi fi - #fi _ } # Add user -addUserXray() { - readConfigHostPathUUID +addUser() { 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" + echoContent red " ---> Trojan does not currently support xtls-rprx-vision" exit 0 fi - # Generate user - if [[ "${userNum}" == "1" ]]; then - customUUID - customUserEmail + local userConfig= + if [[ "${coreInstallType}" == "1" ]]; then + userConfig=".inbounds[0].settings.clients" + elif [[ "${coreInstallType}" == "2" ]]; then + userConfig=".inbounds[0].users" fi while [[ ${userNum} -gt 0 ]]; do + readConfigHostPathUUID 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 + customUUID + customUserEmail + + uuid=${currentCustomUUID} + email=${currentCustomEmail} # VLESS TCP - if echo "${currentInstallProtocolType}" | grep -q "0"; then + 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 + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 0 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 0 "${uuid}" "${email}") + fi + clients=$(jq -r "${userConfig} = ${clients}" ${configPath}02_VLESS_TCP_inbounds.json) + echo "${clients}" | jq . >${configPath}02_VLESS_TCP_inbounds.json fi # VLESS WS - if echo "${currentInstallProtocolType}" | grep -q "1"; then + 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) + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 1 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 1 "${uuid}" "${email}") + fi + + clients=$(jq -r "${userConfig} = ${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 + 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) + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 2 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 2 "${uuid}" "${email}") + fi + + clients=$(jq -r "${userConfig} = ${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 + 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) + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 3 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 3 "${uuid}" "${email}") + fi + + clients=$(jq -r "${userConfig} = ${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 + 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) + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 4 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 4 "${uuid}" "${email}") + fi + clients=$(jq -r "${userConfig} = ${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 + 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) + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 5 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 5 "${uuid}" "${email}") + fi + clients=$(jq -r "${userConfig} = ${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 + 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) + local realityUserConfig= + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 7 "${uuid}" "${email}") + realityUserConfig=".inbounds[1].settings.clients" + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 7 "${uuid}" "${email}") + realityUserConfig=".inbounds[0].users" + fi + clients=$(jq -r "${realityUserConfig} = ${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 + 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 + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 8 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 8 "${uuid}" "${email}") + fi + clients=$(jq -r "${userConfig} = ${clients}" ${configPath}08_VLESS_vision_gRPC_inbounds.json) + echo "${clients}" | jq . >${configPath}08_VLESS_vision_gRPC_inbounds.json fi - # hysteria - if echo "${currentInstallProtocolType}" | grep -q "6"; then + # hysteria2 + 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 + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 6 "${uuid}" "${email}") + elif [[ -n "${singBoxConfigPath}" ]]; then + clients=$(initSingBoxClients 6 "${uuid}" "${email}") + fi + + clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}06_hysteria2_inbounds.json") + echo "${clients}" | jq . >"${singBoxConfigPath}06_hysteria2_inbounds.json" fi - if echo ${currentInstallProtocolType} | grep -q 9; then - local tuicResult + # tuic + if echo ${currentInstallProtocolType} | grep -q ",9,"; then + local clients= + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 9 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 9 "${uuid}" "${email}") + fi - tuicResult=$(jq -r ".users.\"${uuid}\" += \"${uuid}\"" "${tuicConfigPath}config.json") - echo "${tuicResult}" | jq . >"${tuicConfigPath}config.json" + clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}09_tuic_inbounds.json") + + echo "${clients}" | jq . >"${singBoxConfigPath}09_tuic_inbounds.json" + fi + # naive + if echo ${currentInstallProtocolType} | grep -q ",10,"; then + local clients= + clients=$(initSingBoxClients 10 "${uuid}" "${email}") + clients=$(jq -r ".inbounds[0].users = ${clients}" "${singBoxConfigPath}10_naive_inbounds.json") + + echo "${clients}" | jq . >"${singBoxConfigPath}10_naive_inbounds.json" + fi + # VMess WS + if echo "${currentInstallProtocolType}" | grep -q ",11,"; then + local clients= + if [[ "${coreInstallType}" == "1" ]]; then + clients=$(initXrayClients 11 "${uuid}" "${email}") + elif [[ "${coreInstallType}" == "2" ]]; then + clients=$(initSingBoxClients 11 "${uuid}" "${email}") + fi + + clients=$(jq -r "${userConfig} = ${clients}" ${configPath}11_VMess_HTTPUpgrade_inbounds.json) + echo "${clients}" | jq . >${configPath}11_VMess_HTTPUpgrade_inbounds.json + fi + # anytls + if echo "${currentInstallProtocolType}" | grep -q ",13,"; then + local clients= + clients=$(initSingBoxClients 13 "${uuid}" "${email}") + + clients=$(jq -r "${userConfig} = ${clients}" ${configPath}13_anytls_inbounds.json) + echo "${clients}" | jq . >${configPath}13_anytls_inbounds.json fi done - reloadCore - echoContent green " ---> Adding completed" + 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" + readNginxSubscribe + if [[ -n "${subscribePort}" ]]; then + subscribe false + fi manageAccount 1 } -# Add user -addUser() { - - 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 - - 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}_${uuid} - else - email=${currentHost}_${uuid} - fi - - #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 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 - - if echo ${currentInstallProtocolType} | grep -q trojan; then - local trojanXTLSUsers="${users//\,\"alterId\":0/}" - trojanXTLSUsers="${trojanXTLSUsers//${email}/${email}_Trojan_TCP}" - trojanXTLSUsers=${trojanXTLSUsers//"id"/"password"} - - 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 2; then - local trojangRPCUsers="${users//\"flow\":\"xtls-rprx-vision\"\,/}" - trojangRPCUsers="${trojangRPCUsers//${email}/${email}_Trojan_gRPC}" - 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 - - 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 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 - - 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}" - - 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 " ---> Adding completed" - manageAccount 1 -} - # 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}' + if [[ "${coreInstallType}" == "1" ]]; then + jq -r -c '(.inbounds[0].settings.clients // .inbounds[1].settings.clients)[]?|.email' ${configPath}${frontingType:-$frontingTypeReality}.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" + if [[ $(jq -r '(.inbounds[0].settings.clients // .inbounds[1].settings.clients)?|length' ${configPath}${frontingType:-$frontingTypeReality}.json) -lt ${delUserIndex} ]]; then + echoContent red " ---> Not installed, please use script to install" 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}' + elif [[ "${coreInstallType}" == "2" ]]; then + jq -r -c .inbounds[0].users[].name//.inbounds[0].users[].username ${configPath}${frontingType:-$frontingTypeReality}.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" + if [[ $(jq -r '.inbounds[0].users|length' ${configPath}${frontingType:-$frontingTypeReality}.json) -lt ${delUserIndex} ]]; then + echoContent red " ---> Available types are not installed" 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 [[ -n "${delUserIndex}" ]]; then - if echo ${currentInstallProtocolType} | grep -q 1; then + + if echo ${currentInstallProtocolType} | grep -q ",0,"; then + local vlessVision + vlessVision=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}02_VLESS_TCP_inbounds.json) + echo "${vlessVision}" | jq . >${configPath}02_VLESS_TCP_inbounds.json + fi + if echo ${currentInstallProtocolType} | grep -q ",1,"; then local vlessWSResult - vlessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}03_VLESS_WS_inbounds.json) + vlessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}03_VLESS_WS_inbounds.json) echo "${vlessWSResult}" | jq . >${configPath}03_VLESS_WS_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 2; then + if echo ${currentInstallProtocolType} | grep -q ",2,"; then local trojangRPCUsers - trojangRPCUsers=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}04_trojan_gRPC_inbounds.json) + trojangRPCUsers=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"')' ${configPath}04_trojan_gRPC_inbounds.json) echo "${trojangRPCUsers}" | jq . >${configPath}04_trojan_gRPC_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 3; then + if echo ${currentInstallProtocolType} | grep -q ",3,"; then local vmessWSResult - vmessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}05_VMess_WS_inbounds.json) + vmessWSResult=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}05_VMess_WS_inbounds.json) echo "${vmessWSResult}" | jq . >${configPath}05_VMess_WS_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 5; then + if echo ${currentInstallProtocolType} | grep -q ",5,"; then local vlessGRPCResult - vlessGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}06_VLESS_gRPC_inbounds.json) + vlessGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}06_VLESS_gRPC_inbounds.json) echo "${vlessGRPCResult}" | jq . >${configPath}06_VLESS_gRPC_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 4; then + if echo ${currentInstallProtocolType} | grep -q ",4,"; then local trojanTCPResult - trojanTCPResult=$(jq -r 'del(.inbounds[0].settings.clients['${delUserIndex}'])' ${configPath}04_trojan_TCP_inbounds.json) + trojanTCPResult=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}04_trojan_TCP_inbounds.json) echo "${trojanTCPResult}" | jq . >${configPath}04_trojan_TCP_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 6; then + 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 + hysteriaResult=$(jq -r 'del(.inbounds[0].users['"${delUserIndex}"'])' "${singBoxConfigPath}06_hysteria2_inbounds.json") + echo "${hysteriaResult}" | jq . >"${singBoxConfigPath}06_hysteria2_inbounds.json" fi - - if echo ${currentInstallProtocolType} | grep -q 7; then + 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) + vlessRealityResult=$(jq -r 'del(.inbounds[1].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${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 + 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 + vlessRealityGRPCResult=$(jq -r 'del(.inbounds[0].settings.clients['"${delUserIndex}"']//.inbounds[0].users['"${delUserIndex}"'])' ${configPath}08_VLESS_vision_gRPC_inbounds.json) + echo "${vlessRealityGRPCResult}" | jq . >${configPath}08_VLESS_vision_gRPC_inbounds.json fi - if echo ${currentInstallProtocolType} | grep -q 9; then + if echo ${currentInstallProtocolType} | grep -q ",9,"; then local tuicResult - tuicResult=$(jq -r "del(.users.\"${uuid}\")" "${tuicConfigPath}config.json") - echo "${tuicResult}" | jq . >"${tuicConfigPath}config.json" + tuicResult=$(jq -r 'del(.inbounds[0].users['"${delUserIndex}"'])' "${singBoxConfigPath}09_tuic_inbounds.json") + echo "${tuicResult}" | jq . >"${singBoxConfigPath}09_tuic_inbounds.json" + fi + if echo ${currentInstallProtocolType} | grep -q ",10,"; then + local naiveResult + naiveResult=$(jq -r 'del(.inbounds[0].users['"${delUserIndex}"'])' "${singBoxConfigPath}10_naive_inbounds.json") + echo "${naiveResult}" | jq . >"${singBoxConfigPath}10_naive_inbounds.json" + fi + # VMess HTTPUpgrade + if echo ${currentInstallProtocolType} | grep -q ",11,"; then + local vmessHTTPUpgradeResult + vmessHTTPUpgradeResult=$(jq -r 'del(.inbounds[0].users['"${delUserIndex}"'])' "${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json") + echo "${vmessHTTPUpgradeResult}" | jq . >"${singBoxConfigPath}11_VMess_HTTPUpgrade_inbounds.json" + echo "${vmessHTTPUpgradeResult}" | jq . >${configPath}11_VMess_HTTPUpgrade_inbounds.json + fi + # AnyTLS + if echo ${currentInstallProtocolType} | grep -q ",13,"; then + local anyTLSResult + anyTLSResult=$(jq -r 'del(.inbounds[0].users['"${delUserIndex}"'])' "${singBoxConfigPath}13_anytls_inbounds.json") + echo "${anyTLSResult}" | jq . >"${singBoxConfigPath}13_anytls_inbounds.json" fi reloadCore + readNginxSubscribe + if [[ -n "${subscribePort}" ]]; then + subscribe false + fi fi manageAccount 1 } # update script updateV2RayAgent() { - echoContent skyBlue "\nProgress$1/${totalProgress}: Update v2ray-agent script" + echoContent skyBlue "\n================================ Tuic TLS ================================\n" rm -rf /etc/v2ray-agent/install.sh + if [[ "${release}" == "alpine" ]]; then + wget -c -q -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" + else # 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" + wget -c -q "${wgetShowProgressStatus}" -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" + fi + #else # wget -c -q -P /etc/v2ray-agent/ -N --no-check-certificate "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/install.sh" #fi @@ -5208,10 +6239,10 @@ updateV2RayAgent() { 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 fails, please manually execute the following command\n" + 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" + echoContent yellow "5.Unlock encrypted music file template [https://github.com/ix64/unlock-music]" + 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" + echoContent yellow "6.mikutap[https://github.com/HFIProgramming/mikutap]" 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 @@ -5222,27 +6253,27 @@ 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" + 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" 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" + 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" fi } # Install BBR bbrInstall() { - 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 "================================================== ===============" + echoContent red "\n==============================================================" + 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" + echoContent yellow "7.Enterprise Station 02" + echoContent yellow "8.Personal blog 02" + 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 + wget -O tcpx.sh "https://github.com/ylx2016/Linux-NetSpeed/raw/master/tcpx.sh" && chmod +x tcpx.sh && ./tcpx.sh else menu fi @@ -5250,8 +6281,12 @@ bbrInstall() { # View and check logs checkLog() { + if [[ "${coreInstallType}" == "2" ]]; then + echoContent red "\n================================================ =================" + exit 0 + fi if [[ -z "${configPath}" && -z "${realityStatus}" ]]; then - echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + echoContent red "================================================== ===============" exit 0 fi local realityLogShow= @@ -5260,22 +6295,22 @@ checkLog() { logStatus=true fi - echoContent skyBlue "\nFunction$1/${totalProgress}: View log" - echoContent red "\n================================================ =================" - echoContent yellow "# It is recommended to only open the access log during debugging\n" + echoContent skyBlue "\n --->Account:${tuicEmail}_tuic" + echoContent red "\n==============================================================" + echoContent yellow "9.404 automatically jumps to baidu" if [[ "${logStatus}" == "false" ]]; then - echoContent yellow "1.Open access log" + echoContent yellow "10.302 redirect website" else - echoContent yellow "1.Close access log" + 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." fi - 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 "================================================== ===============" + 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 yellow "# Notes\n" + echoContent yellow "Support batch addition" + echoContent red "==============================================================" read -r -p "Please select:" selectAccessLogType local configPathLog=${configPath//conf\//} @@ -5305,19 +6340,24 @@ EOF EOF fi - if [[ -n ${realityStatus} ]]; then + if [[ ${realityStatus} == "7" ]]; 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 + if [[ ${realityStatus} == "12" ]]; then + local vlessVisionRealityXHTTPInbounds + vlessVisionRealityXHTTPInbounds=$(jq -r ".inbounds[0].streamSettings.realitySettings.show=${realityLogShow}" ${configPath}12_VLESS_XHTTP_inbounds.json) + echo "${vlessVisionRealityXHTTPInbounds}" | jq . >${configPath}12_VLESS_XHTTP_inbounds.json + fi reloadCore checkLog 1 ;; 2) - tail -f ${configPathLog}access.log + tail -f "${configPathLog}access.log" ;; 3) - tail -f ${configPathLog}error.log + tail -f "${configPathLog}error.log" ;; 4) if [[ ! -f "/etc/v2ray-agent/crontab_tls.log" ]]; then @@ -5329,8 +6369,8 @@ EOF tail -n 100 /etc/v2ray-agent/tls/acme.log ;; 6) - echo >${configPathLog}access.log - echo >${configPathLog}error.log + echo >"${configPathLog}access.log" + echo >"${configPathLog}error.log" ;; esac } @@ -5358,17 +6398,17 @@ aliasInstall() { 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" + echoContent green "Protocol type: Tuic, address: ${currentHost}, port: ${tuicPort}, uuid: ${id}, password: ${id}, congestion-controller:${tuicAlgorithm}, alpn: h3, account Name:${email}_tuic\n" fi fi } # Check ipv6, ipv4 checkIPv6() { - currentIPv6IP=$(curl -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) + currentIPv6IP=$(curl -s -6 -m 4 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2) if [[ -z "${currentIPv6IP}" ]]; then - echoContent red " ---> does not support ipv6" + echoContent red "\n ---> uuid reading error, randomly generated" exit 0 fi } @@ -5376,117 +6416,170 @@ checkIPv6() { # ipv6 offload ipv6Routing() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" + echoContent red "\n================================================ =================" menu exit 0 fi 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 "================================================== ===============" + echoContent skyBlue "\nProgress$1/${totalProgress}: Change disguise site" + echoContent red "\n==============================================================" + 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 red "==============================================================" read -r -p "Please select:" ipv6Status if [[ "${ipv6Status}" == "1" ]]; then - - jq -r -c '.routing.rules[]|select (.outboundTag=="IPv6-out")|.domain' ${configPath}09_routing.json | jq -r + showIPv6Routing 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" + echoContent red "==============================================================" + echoContent yellow "Input example:2053,2083,2087\n" + echoContent yellow "1.Check the added port" + echoContent yellow "2.Add port" read -r -p "Please enter the domain name according to the above example:" domainList - addInstallRouting IPv6-out outboundTag "${domainList}" + if [[ "${coreInstallType}" == "1" ]]; then + addXrayRouting IPv6_out outboundTag "${domainList}" + addXrayOutbound IPv6_out + fi - unInstallOutbounds IPv6-out + if [[ -n "${singBoxConfigPath}" ]]; then + addSingBoxRouteRule "IPv6_out" "${domainList}" "IPv6_route" + addSingBoxOutbound 01_direct_outbound + addSingBoxOutbound IPv6_out + addSingBoxOutbound IPv4_out + fi - outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","settings":{"domainStrategy":"UseIPv6"},"tag":"IPv6-out"}]' ${configPath}10_ipv4_outbounds.json) - - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - - echoContent green " ---> Added successfully" + echoContent green "${v2rayNConf}" 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" + + echoContent red "==============================================================" + echoContent yellow "3.Delete port" + echoContent yellow "\n ---> The number entered is wrong, please choose again" + echoContent yellow " ---> The script will not delete acme related configurations. To delete, please execute manually [rm -rf /root/.acme.sh]" 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 - rm ${configPath}09_routing.json >/dev/null 2>&1 - echoContent green " ---> IPv6 global outbound setting successful" + if [[ "${coreInstallType}" == "1" ]]; then + addXrayOutbound IPv6_out + removeXrayOutbound IPv4_out + removeXrayOutbound z_direct_outbound + removeXrayOutbound blackhole_out + removeXrayOutbound wireguard_out_IPv4 + removeXrayOutbound wireguard_out_IPv6 + removeXrayOutbound socks5_outbound + + rm ${configPath}09_routing.json >/dev/null 2>&1 + fi + if [[ -n "${singBoxConfigPath}" ]]; then + + removeSingBoxConfig IPv4_out + + removeSingBoxConfig wireguard_endpoints_IPv4_route + removeSingBoxConfig wireguard_endpoints_IPv6_route + removeSingBoxConfig wireguard_endpoints_IPv4 + removeSingBoxConfig wireguard_endpoints_IPv6 + + removeSingBoxConfig socks5_02_inbound_route + + removeSingBoxConfig IPv6_route + + removeSingBoxConfig 01_direct_outbound + + addSingBoxOutbound IPv6_out + + fi + + echoContent green " ---> 302 redirection set up successfully" else - echoContent green " ---> Abandon settings" + + echoContent green " ---> nginx configuration file backup successful" exit 0 fi elif [[ "${ipv6Status}" == "4" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + unInstallRouting IPv6_out outboundTag - unInstallRouting IPv6-out outboundTag - - unInstallOutbounds IPv6-out - - 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) - - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + removeXrayOutbound IPv6_out + addXrayOutbound "z_direct_outbound" fi - echoContent green " ---> IPv6 offload uninstall successful" + + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxConfig IPv6_out + removeSingBoxConfig "IPv6_route" + addSingBoxOutbound "01_direct_outbound" + fi + + echoContent green " ---> nginx configuration file restoration backup successful" else - echoContent red " ---> Wrong selection" + echoContent red "\nIf you don't understand Cloudflare optimization, please do not use it" exit 0 fi reloadCore } +showIPv6Routing() { + if [[ "${coreInstallType}" == "1" ]]; then + if [[ -f "${configPath}09_routing.json" ]]; then + echoContent yellow "Xray-core:" + jq -r -c '.routing.rules[]|select (.outboundTag=="IPv6_out")|.domain' ${configPath}09_routing.json | jq -r + elif [[ ! -f "${configPath}09_routing.json" && -f "${configPath}IPv6_out.json" ]]; then + echoContent yellow "Xray-core" + echoContent green " ---> Removed 302 redirect successfully" + else + echoContent yellow "1.CNAME www.digitalocean.com" + fi + + fi + if [[ -n "${singBoxConfigPath}" ]]; then + if [[ -f "${singBoxConfigPath}IPv6_route.json" ]]; then + echoContent yellow "sing-box" + jq -r -c '.route.rules[]|select (.outbound=="IPv6_out")' "${singBoxConfigPath}IPv6_route.json" | jq -r + elif [[ ! -f "${singBoxConfigPath}IPv6_route.json" && -f "${singBoxConfigPath}IPv6_out.json" ]]; then + echoContent yellow "sing-box" + echoContent green " ---> Pseudo site replaced successfully" + else + echoContent yellow "2.CNAME who.int" + fi + fi +} # bt download management btTools() { + if [[ "${coreInstallType}" == "2" ]]; then + echoContent red " ---> Failed to read configuration, please reinstall" + exit 0 + fi if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" + 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" menu exit 0 fi - echoContent skyBlue "\nFunction 1/${totalProgress}: bt download management" - echoContent red "\n================================================ =================" + echoContent skyBlue "\nFunction 1/${totalProgress}: Add new port" + echoContent red "\n==============================================================" if [[ -f ${configPath}09_routing.json ]] && grep -q bittorrent <${configPath}09_routing.json; then - echoContent yellow "Current status: disabled" + echoContent yellow "3.CNAME blog.hostmonit.com" else - echoContent yellow "Current status: not disabled" + echoContent yellow "4.Manual input [can enter multiple, such as:1.1.1.1,1.1.2.2, cloudflare.com separated by commas]" fi - echoContent yellow "1.Disable" - echoContent yellow "2.Open" - echoContent red "================================================== ===============" + echoContent yellow "5.Remove CDN node" + echoContent yellow "1.Add user" + echoContent red "==============================================================" read -r -p "Please select:" btStatus if [[ "${btStatus}" == "1" ]]; then if [[ -f "${configPath}09_routing.json" ]]; then - unInstallRouting blackhole-out outboundTag + unInstallRouting blackhole_out outboundTag bittorrent - 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 @@ -5498,7 +6591,7 @@ btTools() { "rules": [ { "type": "field", - "outboundTag": "blackhole-out", + "outboundTag": "blackhole_out", "protocol": [ "bittorrent" ] } ] @@ -5508,26 +6601,20 @@ EOF fi installSniffing + removeXrayOutbound blackhole_out + addXrayOutbound blackhole_out - 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 " ---> BT download disabled successfully" + echoContent green " ---> Added successfully" elif [[ "${btStatus}" == "2" ]]; then unInstallSniffing - unInstallRouting blackhole-out outboundTag bittorrent + unInstallRouting blackhole_out outboundTag bittorrent - # unInstallOutbounds blackhole-out - - echoContent green " ---> BT download opened successfully" + echoContent green " ---> Give up uninstalling" else - echoContent red " ---> Wrong selection" + echoContent red " ---> not installed" exit 0 fi @@ -5537,108 +6624,143 @@ EOF # Domain name blacklist blacklist() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" + echoContent red " ---> 302 redirection setting failed, please double check whether it is the same as the example" menu exit 0 fi - 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 + IP" - echoContent yellow "4.Delete blacklist/whitelist" - echoContent yellow "5.Add blocked IP" - echoContent yellow "6.Add domain whitelist" - echoContent red "================================================== ===============" + echoContent skyBlue "\nProgress$1/${totalProgress}: Modify CDN node" + echoContent red "\n==============================================================" + echoContent yellow "2.Delete user" + echoContent yellow "uuid:${currentCustomUUID}\n" + echoContent yellow "email: ${currentCustomEmail}\n" + echoContent yellow "After adding a new user, you need to check the subscription again" + echoContent yellow " ---> Please manually execute [vasma] to open the script" + echoContent yellow "If the update fails, please manually execute the following command\n" + echoContent red "==============================================================" 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 + 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" + echoContent red "==============================================================" + echoContent yellow "1.Installation script [recommended original BBR+FQ]" + echoContent yellow "2.Return to the home directory" + echoContent yellow "# It is recommended to only open the access log during debugging\n" + echoContent yellow "1.Open access log" + echoContent yellow "1.Close access log" + echoContent yellow "2.Monitor access log" read -r -p "Please enter the domain name according to the above example:" domainList - - if [[ -f "${configPath}09_routing.json" ]]; then - addInstallRouting blackhole-out outboundTag "${domainList}" + if [[ "${coreInstallType}" == "1" ]]; then + addXrayRouting blackhole_out outboundTag "${domainList}" + addXrayOutbound blackhole_out fi - 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 " ---> Added successfully" + if [[ -n "${singBoxConfigPath}" ]]; then + addSingBoxRouteRule "block_domain_outbound" "${domainList}" "block_domain_route" + addSingBoxOutbound "block_domain_outbound" + addSingBoxOutbound "01_direct_outbound" + fi + echoContent green " ---> Stop Nginx successfully" elif [[ "${blacklistStatus}" == "3" ]]; then - local autoAllowDomainList="dl.google.com,apple.com,bing.com,microsoft.com,gstatic.cn" - unInstallRouting blackhole-out outboundTag - unInstallRouting blackhole-ip-out outboundTag + local allowDomainList="googleplay.com,play.google.com,play.googleapis.com,play-lh.googleusercontent.com,play-games.googleusercontent.com,play-fe.googleapis.com,dl.google.com,apple.com,apple-pki,apple-tvplus,apple-update,itunes,icloud,beats,bing.com,microsoft.com,gstatic,xn--ngstr-lra8j.com,googleapis.com,googleapis.cn" - addInstallRouting blackhole-out outboundTag "cn" - addInstallIPRouting blackhole-ip-out outboundTag "cn" - addInstallRouting allow-domain-direct-out outboundTag "${autoAllowDomainList}" "top" + if [[ "${coreInstallType}" == "1" ]]; then + unInstallRouting blackhole_out outboundTag + unInstallRouting blackhole_ip_out outboundTag - unInstallOutbounds blackhole-out - unInstallOutbounds blackhole-ip-out - unInstallOutbounds allow-domain-direct-out + addXrayRouting blackhole_out outboundTag "cn" + addXrayIPRouting blackhole_ip_out outboundTag "cn" + addXrayRouting allow_domain_direct_outbound outboundTag "${allowDomainList}" "top" - outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-out"},{"protocol":"blackhole","tag":"blackhole-ip-out"},{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json) + addXrayOutbound blackhole_out + addXrayOutbound blackhole_ip_out + addXrayOutbound allow_domain_direct_outbound + fi - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json + if [[ -n "${singBoxConfigPath}" ]]; then - echoContent green " ---> Domestic domain name + IP blocked successfully" + addSingBoxRouteRule "cn_block_outbound" "cn" "cn_block_route" + addSingBoxGeoIPRouteRule "block_ip_outbound" "cn" "cn_block_ip_route" + addSingBoxRouteRule "01_direct_outbound" "${allowDomainList}" "00_allow_domain_route" + + addSingBoxOutbound "cn_block_outbound" + addSingBoxOutbound "block_ip_outbound" + addSingBoxOutbound "01_direct_outbound" + fi + + echoContent green " ---> Delete Xray and it will start automatically after booting" elif [[ "${blacklistStatus}" == "4" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + unInstallRouting blackhole_out outboundTag + unInstallRouting blackhole_ip_out outboundTag + unInstallRouting allow_domain_direct_outbound outboundTag - unInstallRouting blackhole-out outboundTag - unInstallRouting blackhole-ip-out outboundTag - unInstallRouting allow-domain-direct-out outboundTag + removeXrayOutbound blackhole_ip_out + removeXrayOutbound allow_domain_direct_outbound + fi - unInstallOutbounds blackhole-ip-out - unInstallOutbounds allow-domain-direct-out + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxConfig "cn_block_route" + removeSingBoxConfig "cn_block_outbound" + removeSingBoxConfig "cn_block_ip_route" + removeSingBoxConfig "block_ip_route" + removeSingBoxConfig "block_ip_outbound" - echoContent green " ---> Domain blacklist/whitelist deleted successfully" + removeSingBoxConfig "cn_01_google_play_route" + removeSingBoxConfig "00_allow_domain_route" + + removeSingBoxConfig "block_domain_route" + removeSingBoxConfig "block_domain_outbound" + fi + echoContent green " ---> Delete V2Ray and it will start automatically after booting" elif [[ "${blacklistStatus}" == "5" ]]; then - echoContent yellow "Input example:1.1.1.1,8.8.8.8,1.1.1.0/24,2400:3200::/32\n" + echoContent red "==============================================================" + echoContent yellow "3.Monitor error log" read -r -p "Please enter the blocked IP list:" ipList if [[ -z "${ipList}" ]]; then - echoContent red " ---> ip cannot be empty" + echoContent red " ---> 302 Add failed" exit 0 fi - addInstallIPRouting blackhole-ip-out outboundTag "${ipList}" - unInstallOutbounds blackhole-ip-out - outbounds=$(jq -r '.outbounds += [{"protocol":"blackhole","tag":"blackhole-ip-out"}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - echoContent green " ---> Blocked IP added successfully" + if [[ "${coreInstallType}" == "1" ]]; then + addXrayIPRouting blackhole_ip_out outboundTag "${ipList}" + addXrayOutbound blackhole_ip_out + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + addSingBoxIPRouteRule "block_ip_outbound" "${ipList}" "block_ip_route" + addSingBoxOutbound "block_ip_outbound" + fi + echoContent green " ---> Delete Hysteria and it will start automatically after booting" elif [[ "${blacklistStatus}" == "6" ]]; then - echoContent yellow "Input example:speedtest,openai,google.com\n" + echoContent red "==============================================================" + echoContent yellow "4.View certificate scheduled task log" read -r -p "Please enter whitelist domains:" allowDomainList if [[ -z "${allowDomainList}" ]]; then - echoContent red " ---> domain cannot be empty" + echoContent red "\n ---> Due to environmental dependencies, please install Xray-core's VLESS_TCP_TLS_Vision first" exit 0 fi - addInstallRouting allow-domain-direct-out outboundTag "${allowDomainList}" "top" - unInstallOutbounds allow-domain-direct-out - outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - echoContent green " ---> Domain whitelist added successfully" + if [[ "${coreInstallType}" == "1" ]]; then + addXrayRouting allow_domain_direct_outbound outboundTag "${allowDomainList}" "top" + addXrayOutbound allow_domain_direct_outbound + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + addSingBoxRouteRule "01_direct_outbound" "${allowDomainList}" "00_allow_domain_route" + addSingBoxOutbound "01_direct_outbound" + fi + echoContent green " ---> Delete Tuic and start automatically after booting" else - echoContent red " ---> Wrong selection" + echoContent red "================================================== =========== ====" exit 0 fi reloadCore } - # Download dlc.dat_plain.yml into core directory downloadDLCPlainYAML() { local corePath=$1 @@ -5653,15 +6775,15 @@ downloadDLCPlainYAML() { if [[ -s "${dlcFilePath}" ]]; then return 0 fi - local dlcDownloadURL="https://github.com/v2fly/domain-list-community/releases/latest/download/dlc.dat_plain.yml" if [[ "${release}" == "alpine" ]]; then - wget -c -q -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1 + wget -c -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1 else - wget -c -q "${wgetShowProgressStatus}" -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1 + wget -c "${wgetShowProgressStatus}" -O "${tmpFilePath}" "${dlcDownloadURL}" >/dev/null 2>&1 fi - if [[ $? -ne 0 || ! -s "${tmpFilePath}" ]]; then + # shellcheck disable=SC2181 + if [[ "$?" -ne 0 || ! -s "${tmpFilePath}" ]]; then rm -f "${tmpFilePath}" >/dev/null 2>&1 return 1 fi @@ -5671,7 +6793,9 @@ downloadDLCPlainYAML() { # Escape grep/regex pattern meta characters escapeDLCRegexPattern() { - echo "$1" | sed -e 's/[.[\\*^$()+?{|]/\\\\&/g' + # shellcheck disable=SC2016 + # shellcheck disable=SC2001 + echo "$1" | sed -e 's/[.[\*^$()+?{|]/\\&/g' } # Resolve nearest upper name by matched rule line @@ -5759,16 +6883,15 @@ getDLCMatchedRuleValue() { fi } -#Add routing configuration -addInstallRouting() { +addXrayRouting() { local tag=$1 # warp-socks local type=$2 # outboundTag/inboundTag - local domain=$3 # Domain name + local domain=$3 # domain local rulePosition=$4 if [[ -z "${tag}" || -z "${type}" || -z "${domain}" ]]; then - echoContent red " ---> Parameter error" + echoContent red "================================================== ===============" exit 0 fi @@ -5791,20 +6914,15 @@ addInstallRouting() { EOF fi local routingRule= - routingRule=$(jq -r '.routing.rules[]|select(.outboundTag=="'"${tag}"'")' ${configPath}09_routing.json) + routingRule=$(jq -r ".routing.rules[]|select(.outboundTag==\"${tag}\" and (.protocol == null))" ${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 + routingRule="{\"type\": \"field\",\"domain\": [],\"outboundTag\": \"${tag}\"}" fi while read -r line; do if echo "${routingRule}" | grep -q "${line}"; then - echoContent yellow " ---> ${line} already exists, skip" + echoContent yellow "5.View certificate installation log" else local matchedRuleValue matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray") @@ -5813,16 +6931,11 @@ EOF done < <(echo "${domain}" | tr ',' '\n') unInstallRouting "${tag}" "${type}" - if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole-out" ]]; then + if ! grep -q "gstatic.com" ${configPath}09_routing.json && [[ "${tag}" == "blackhole_out" ]]; then local routing= - routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"domain:gstatic.com\"],\"outboundTag\": \"allow-domain-direct-out\"}]" ${configPath}09_routing.json) + routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": [\"domain:gstatic.com\"],\"outboundTag\": \"allow_domain_direct_outbound\"}]" ${configPath}09_routing.json) echo "${routing}" | jq . >${configPath}09_routing.json - - if [[ -f "${configPath}10_ipv4_outbounds.json" ]] && ! grep -q '"allow-domain-direct-out"' "${configPath}10_ipv4_outbounds.json"; then - local outbounds= - outbounds=$(jq -r '.outbounds += [{"protocol":"freedom","tag":"allow-domain-direct-out","settings":{"domainStrategy":"UseIP"}}]' ${configPath}10_ipv4_outbounds.json) - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - fi + addXrayOutbound allow_domain_direct_outbound fi if [[ "${rulePosition}" == "top" ]]; then @@ -5833,16 +6946,14 @@ EOF echo "${routing}" | jq . >${configPath}09_routing.json } -# Add Xray IP block routing -# Supports geoip:cn and custom IPv4/IPv6/CIDR input -addInstallIPRouting() { +addXrayIPRouting() { local tag=$1 local type=$2 local ipList=$3 if [[ -z "${tag}" || -z "${type}" || -z "${ipList}" ]]; then - echoContent red " ---> Parameter error" + echoContent red "\n================================================ =================" exit 0 fi @@ -5875,7 +6986,7 @@ EOF fi if echo "${routingRule}" | grep -q "${ipRuleValue}"; then - echoContent yellow " ---> ${ipRuleValue} already exists, skip" + echoContent yellow "6.Clear the log" else routingRule=$(echo "${routingRule}" | jq -r '.ip += ["'"${ipRuleValue}"'"]') fi @@ -5886,6 +6997,67 @@ EOF routing=$(jq -r ".routing.rules += [${routingRule}]" ${configPath}09_routing.json) echo "${routing}" | jq . >${configPath}09_routing.json } + +addSingBoxIPRouteRule() { + local outboundTag=$1 + local ipList=$2 + local routingName=$3 + + local historyIPs= + if [[ -f "${singBoxConfigPath}${routingName}.json" ]]; then + historyIPs=$(jq -r '.route.rules[0].ip_cidr[]?' "${singBoxConfigPath}${routingName}.json" | paste -sd ',') + fi + + if [[ -n "${historyIPs}" ]]; then + ipList="${ipList},${historyIPs}" + fi + + local ipCIDR=[] + ipCIDR=$(echo "${ipList}" | tr ',' '\n' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//' | grep -v '^$' | sort -n | uniq | jq -R . | jq -s .) + + cat <"${singBoxConfigPath}${routingName}.json" +{ + "route": { + "rules": [ + { + "ip_cidr": ${ipCIDR}, + "outbound": "${outboundTag}" + } + ] + } +} +EOF +} + +addSingBoxGeoIPRouteRule() { + local outboundTag=$1 + local geoipCode=$2 + local routingName=$3 + + cat <"${singBoxConfigPath}${routingName}.json" +{ + "route": { + "rules": [ + { + "rule_set": [ + "geoip_${geoipCode}_${routingName}" + ], + "outbound": "${outboundTag}" + } + ], + "rule_set": [ + { + "tag": "geoip_${geoipCode}_${routingName}", + "type": "remote", + "format": "binary", + "url": "https://raw.githubusercontent.com/SagerNet/sing-geoip/rule-set/geoip-${geoipCode}.srs", + "http_client": "rule_set_http" + } + ] + } +} +EOF +} # Uninstall Routing based on tag unInstallRouting() { local tag=$1 @@ -5893,48 +7065,17 @@ unInstallRouting() { local protocol=$3 if [[ -f "${configPath}09_routing.json" ]]; then - local routing - if grep -q "${tag}" ${configPath}09_routing.json && grep -q "${type}" ${configPath}09_routing.json; then - - jq -c .routing.rules[] ${configPath}09_routing.json | while read -r line; do - local index=$((index + 1)) - local delStatus=0 - if [[ "${type}" == "outboundTag" ]] && echo "${line}" | jq .outboundTag | grep -q "${tag}"; then - 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 - 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 + local routing= + if [[ -n "${protocol}" ]]; then + routing=$(jq -r "del(.routing.rules[] | select(.${type} == \"${tag}\" and (.protocol | index(\"${protocol}\"))))" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json + else + routing=$(jq -r "del(.routing.rules[] | select(.${type} == \"${tag}\" and (.protocol == null )))" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json fi fi } -# Uninstall outbound based on tag -unInstallOutbounds() { - 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 - -} - # Uninstall sniffing unInstallSniffing() { @@ -5950,110 +7091,14 @@ unInstallSniffing() { # Install sniffing installSniffing() { 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 diversion -warpRouting() { - 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 + if [[ "${coreInstallType}" == "1" ]]; then + if [[ -f "${configPath}02_VLESS_TCP_inbounds.json" ]]; then + if ! grep -q "destOverride" <"${configPath}02_VLESS_TCP_inbounds.json"; then + sniffing=$(jq -r '.inbounds[0].sniffing = {"enabled":true,"destOverride":["http","tls","quic"]}' "${configPath}02_VLESS_TCP_inbounds.json") + echo "${sniffing}" | jq . >"${configPath}02_VLESS_TCP_inbounds.json" + fi 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 - 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" - - read -r -p "Please enter the domain name according to the above example:" domainList - - addInstallRouting warp-socks-out outboundTag "${domainList}" - - unInstallOutbounds warp-socks-out - - 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 -{ -"outbounds":[ -{ -"protocol": "socks", -"settings": { -"servers": [ -{ -"address": "127.0.0.1", -"port": 31303 -} -] -}, -"tag": "warp-socks-out" -} -] -} -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 - - ${removeType} cloudflare-warp >/dev/null 2>&1 - - unInstallRouting warp-socks-out outboundTag - - unInstallOutbounds warp-socks-out - - 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) - - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - fi - - echoContent green " ---> WARP offload uninstall successful" - else - echoContent red " ---> Wrong selection" - exit 0 - fi - reloadCore } # Read third-party warp configuration @@ -6071,16 +7116,12 @@ readConfigWarpReg() { 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 "================================================== ===============" +installWarpReg() { 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" + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Set IPv6 global" read -r -p "warp-reg is not installed, do you want to install it? [y/n]:" installWarpRegStatus @@ -6090,18 +7131,121 @@ warpRoutingReg() { chmod 655 /etc/v2ray-agent/warp/warp-reg else - echoContent yellow " ---> Abort installation" + echoContent yellow "4.Uninstall IPv6 offloading" 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 +} +showWireGuardDomain() { + local type=$1 + # xray + if [[ "${coreInstallType}" == "1" ]]; then + if [[ -f "${configPath}09_routing.json" ]]; then + echoContent yellow "Xray-core" + jq -r -c '.routing.rules[]|select (.outboundTag=="wireguard_out_'"${type}"'")|.domain' ${configPath}09_routing.json | jq -r + elif [[ ! -f "${configPath}09_routing.json" && -f "${configPath}wireguard_out_${type}.json" ]]; then + echoContent yellow "Xray-core" + echoContent green " ---> Deletion of fake website completed" + else + echoContent yellow "# Notes\n" + fi + fi + + # sing-box + if [[ -n "${singBoxConfigPath}" ]]; then + if [[ -f "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" ]]; then + echoContent yellow "sing-box" + jq -r -c '.route.rules[]' "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" | jq -r + elif [[ ! -f "${singBoxConfigPath}wireguard_endpoints_${type}_route.json" && -f "${singBoxConfigPath}wireguard_endpoints_${type}.json" ]]; then + echoContent yellow "sing-box" + echoContent green " ---> Uninstallation of shortcut completed" + else + echoContent yellow "# Notes" + fi + fi + +} + +addWireGuardRoute() { + local type=$1 + local tag=$2 + local domainList=$3 + # xray + if [[ "${coreInstallType}" == "1" ]]; then + + addXrayRouting "wireguard_out_${type}" "${tag}" "${domainList}" + addXrayOutbound "wireguard_out_${type}" + fi + # sing-box + if [[ -n "${singBoxConfigPath}" ]]; then + + # rule + addSingBoxRouteRule "wireguard_endpoints_${type}" "${domainList}" "wireguard_endpoints_${type}_route" + # addSingBoxOutbound "wireguard_out_${type}" "wireguard_out" + if [[ -n "${domainList}" ]]; then + addSingBoxOutbound "01_direct_outbound" + fi + + # outbound + addSingBoxWireGuardEndpoints "${type}" + fi +} + +unInstallWireGuard() { + local type=$1 + if [[ "${coreInstallType}" == "1" ]]; then + + if [[ "${type}" == "IPv4" ]]; then + if [[ ! -f "${configPath}wireguard_out_IPv6.json" ]]; then + rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1 + fi + elif [[ "${type}" == "IPv6" ]]; then + if [[ ! -f "${configPath}wireguard_out_IPv4.json" ]]; then + rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1 + fi + fi + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + if [[ ! -f "${singBoxConfigPath}wireguard_endpoints_IPv6_route.json" && ! -f "${singBoxConfigPath}wireguard_endpoints_IPv4_route.json" ]]; then + rm "${singBoxConfigPath}wireguard_outbound.json" >/dev/null 2>&1 + rm -rf /etc/v2ray-agent/warp/config >/dev/null 2>&1 + fi + fi +} +removeWireGuardRoute() { + local type=$1 + if [[ "${coreInstallType}" == "1" ]]; then + + unInstallRouting wireguard_out_"${type}" outboundTag + + removeXrayOutbound "wireguard_out_${type}" + if [[ ! -f "${configPath}IPv4_out.json" ]]; then + addXrayOutbound IPv4_out + fi + fi + + # sing-box + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxRouteRule "wireguard_endpoints_${type}" + fi + + unInstallWireGuard "${type}" +} +# warp offload-third-party IPv4 +warpRoutingReg() { + local type=$2 + echoContent skyBlue "\nProgress$1/${totalProgress}: Multi-user management" + echoContent red "==============================================================" + + echoContent yellow "# Tutorial: https://www.v2ray-agent.com/archives/ba-he-yi-jiao-ben-yu-ming-fen-liu-jiao-cheng \n" + 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" + echoContent red "==============================================================" + read -r -p "Please select:" warpStatus + installWarpReg readConfigWarpReg local address= if [[ ${type} == "IPv4" ]]; then @@ -6109,121 +7253,98 @@ warpRoutingReg() { elif [[ ${type} == "IPv6" ]]; then address="${addressWarpReg}/128" else - echoContent red " ---> IP acquisition failed, exit installation" + echoContent red "================================================== ===============" fi if [[ "${warpStatus}" == "1" ]]; then - jq -r -c '.routing.rules[]|select (.outboundTag=="wireguard-out-'"${type}"'")|.domain' ${configPath}09_routing.json | jq -r + showWireGuardDomain "${type}" 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" + echoContent yellow "Current status: disabled" + echoContent yellow "Current status: not disabled" + echoContent yellow "1.Disable" 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" + addWireGuardRoute "${type}" outboundTag "${domainList}" + echoContent green " ---> Uninstall v2ray-agent script completed" 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 + echoContent red "==============================================================" + echoContent yellow "2.Open" + echoContent yellow "1.View blocked domain names" + echoContent yellow "2.Add domain name" + read -r -p "Confirm settings? [y/n]:" warpOutStatus if [[ "${warpOutStatus}" == "y" ]]; then readConfigWarpReg + if [[ "${coreInstallType}" == "1" ]]; then + addXrayOutbound "wireguard_out_${type}" + if [[ "${type}" == "IPv4" ]]; then + removeXrayOutbound "wireguard_out_IPv6" + elif [[ "${type}" == "IPv6" ]]; then + removeXrayOutbound "wireguard_out_IPv4" + fi - 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" + removeXrayOutbound IPv4_out + removeXrayOutbound IPv6_out + removeXrayOutbound z_direct_outbound + removeXrayOutbound blackhole_out + removeXrayOutbound socks5_outbound + + rm ${configPath}09_routing.json >/dev/null 2>&1 + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + + removeSingBoxConfig IPv4_out + removeSingBoxConfig IPv6_out + removeSingBoxConfig 01_direct_outbound + + removeSingBoxConfig wireguard_endpoints_IPv4_route + removeSingBoxConfig wireguard_endpoints_IPv6_route + + removeSingBoxConfig IPv6_route + removeSingBoxConfig socks5_02_inbound_route + + addSingBoxWireGuardEndpoints "${type}" + addWireGuardRoute "${type}" outboundTag "" + if [[ "${type}" == "IPv4" ]]; then + removeSingBoxConfig wireguard_endpoints_IPv6 + else + removeSingBoxConfig wireguard_endpoints_IPv4 + fi + + # outbound + # addSingBoxOutbound "wireguard_out_${type}" "wireguard_out" + + fi + + echoContent green " ---> CDN modified successfully" else - echoContent green " ---> Abandon settings" + echoContent green " ---> Adding completed" exit 0 fi elif [[ "${warpStatus}" == "4" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + unInstallRouting "wireguard_out_${type}" outboundTag - 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 + removeXrayOutbound "wireguard_out_${type}" + addXrayOutbound "z_direct_outbound" fi - if ! grep -q "IPv4-out" <"${configPath}10_ipv4_outbounds.json"; then + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxConfig "wireguard_endpoints_${type}_route" - 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 + removeSingBoxConfig "wireguard_endpoints_${type}" + addSingBoxOutbound "01_direct_outbound" fi - echoContent green " ---> WARP offload uninstall successful" + echoContent green " ---> Adding completed" else - echoContent red " ---> Wrong selection" + + echoContent red " ---> Wrong selection, please select again" exit 0 fi reloadCore @@ -6231,15 +7352,17 @@ EOF # 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" + echoContent skyBlue "------------------------------------------------- ------" + echoContent red "\n==============================================================" + echoContent yellow "3.Block domestic domain names + IP" + echoContent yellow "4.Delete blacklist/whitelist" + + echoContent yellow "5.Add blocked IP" + echoContent yellow "6.Add domain whitelist" + 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" read -r -p "Please select:" selectType @@ -6254,77 +7377,35 @@ routingToolsMenu() { ipv6Routing 1 ;; 4) - dokodemoDoorRouting 1 + socks5Routing ;; 5) dnsRouting 1 ;; - 6) - vmessWSRouting 1 - ;; + # 6) + # if [[ -n "${singBoxConfigPath}" ]]; then + # fi + # vmessWSRouting 1 + # ;; 7) + if [[ -n "${singBoxConfigPath}" ]]; then + echoContent red "\n================================================ =================" + fi sniRouting 1 ;; esac } -#Streaming Toolbox -streamingToolbox() { - 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) - dokodemoDoorRouting - ;; - 2) - dnsRouting - ;; - 3) - vmessWSRouting - ;; - esac - -} - -#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 - - case ${selectType} in - 1) - setDokodemoDoorRoutingOutbounds - ;; - 2) - setDokodemoDoorRoutingInbounds - ;; - 3) - removeDokodemoDoorRouting - ;; - esac -} # 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 skyBlue "------------------------------------------------- ------" + echoContent red "\n==============================================================" + 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" - echoContent yellow "1.Add outbound" - echoContent yellow "2.Uninstall" + echoContent yellow "Input example:1.1.1.1,8.8.8.8,1.1.1.0/24,2400:3200::/32\n" + echoContent yellow "Input example:speedtest,openai,google.com\n" read -r -p "Please select:" selectType case ${selectType} in @@ -6336,226 +7417,600 @@ vmessWSRouting() { ;; esac } +socks5Routing() { + if [[ -z "${coreInstallType}" ]]; then + echoContent red "================================================== ===============" + exit 0 + fi + echoContent skyBlue "\nProgress$1/${totalProgress}: Update v2ray-agent script" + echoContent red "\n==============================================================" + echoContent red "================================================== ===============" + echoContent yellow " ---> ${line} already exists, skip" + + echoContent yellow " ---> ${ipRuleValue} already exists, skip" + echoContent yellow " ---> Abort installation" + + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + echoContent yellow "3.Set WARP global" + read -r -p "Please select:" selectType + + case ${selectType} in + 1) + socks5OutboundRoutingMenu + ;; + 2) + socks5InboundRoutingMenu + ;; + 3) + removeSocks5Routing + ;; + esac +} +socks5InboundRoutingMenu() { + readInstallType + 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" + echoContent red "\n==============================================================" + + echoContent yellow "4.Uninstall WARP distribution" + 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 "# Notes\n" + read -r -p "Please select:" selectType + case ${selectType} in + 1) + totalProgress=1 + installSingBox 1 + installSingBoxService 1 + setSocks5Inbound + setSocks5InboundRouting + reloadCore + socks5InboundRoutingMenu + ;; + 2) + showSingBoxRoutingRules socks5_02_inbound_route + socks5InboundRoutingMenu + ;; + 3) + setSocks5InboundRouting addRules + reloadCore + socks5InboundRoutingMenu + ;; + 4) + if [[ -f "${singBoxConfigPath}20_socks5_inbounds.json" ]]; then + echoContent yellow "1.All diversion rules set will be deleted" + echoContent green "\n ---> Update completed" + echoContent green " ---> Current version: ${version}\n" + echoContent green " ---> ufw closed successfully" + else + echoContent red "================================================== ===============" + socks5InboundRoutingMenu + fi + ;; + esac + +} + +socks5OutboundRoutingMenu() { + echoContent skyBlue "\nFunction$1/${totalProgress}: View log" + echoContent red "\n==============================================================" + + echoContent yellow "2.All outbound rules except WARP will be deleted" + 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 "Please select:" selectType + case ${selectType} in + 1) + setSocks5Outbound + setSocks5OutboundRouting + reloadCore + socks5OutboundRoutingMenu + ;; + 2) + setSocks5Outbound + setSocks5OutboundRoutingAll + reloadCore + socks5OutboundRoutingMenu + ;; + 3) + showSingBoxRoutingRules socks5_01_outbound_route + showXrayRoutingRules socks5_outbound + socks5OutboundRoutingMenu + ;; + 4) + setSocks5OutboundRouting addRules + reloadCore + socks5OutboundRoutingMenu + ;; + esac + +} + +setSocks5OutboundRoutingAll() { + + echoContent red "==============================================================" + echoContent yellow " ---> Abort installation" + echoContent yellow "1.View the diverted domain name" + echoContent yellow "2.Add domain name" + read -r -p "Confirm this setting? [y/n]:" socksOutStatus + + if [[ "${socksOutStatus}" == "y" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + removeXrayOutbound IPv4_out + removeXrayOutbound IPv6_out + removeXrayOutbound z_direct_outbound + removeXrayOutbound blackhole_out + removeXrayOutbound wireguard_out_IPv4 + removeXrayOutbound wireguard_out_IPv6 + + rm ${configPath}09_routing.json >/dev/null 2>&1 + fi + if [[ -n "${singBoxConfigPath}" ]]; then + + removeSingBoxConfig IPv4_out + removeSingBoxConfig IPv6_out + + removeSingBoxConfig wireguard_endpoints_IPv4_route + removeSingBoxConfig wireguard_endpoints_IPv6_route + removeSingBoxConfig wireguard_endpoints_IPv4 + removeSingBoxConfig wireguard_endpoints_IPv6 + + removeSingBoxConfig socks5_01_outbound_route + removeSingBoxConfig 01_direct_outbound + fi + + echoContent green " ---> firewalld closed successfully" + fi +} +showSingBoxRoutingRules() { + if [[ -n "${singBoxConfigPath}" ]]; then + if [[ -f "${singBoxConfigPath}$1.json" ]]; then + jq .route.rules "${singBoxConfigPath}$1.json" + elif [[ "$1" == "socks5_01_outbound_route" && -f "${singBoxConfigPath}socks5_outbound.json" ]]; then + echoContent yellow "3.Set WARP global" + echoContent yellow "4.Uninstall WARP distribution" + echoContent skyBlue "$(jq .outbounds[0] ${singBoxConfigPath}socks5_outbound.json)" + elif [[ "$1" == "socks5_02_inbound_route" && -f "${singBoxConfigPath}20_socks5_inbounds.json" ]]; 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" + echoContent skyBlue "$(jq .outbounds[0] ${singBoxConfigPath}socks5_outbound.json)" + fi + fi +} + +showXrayRoutingRules() { + if [[ "${coreInstallType}" == "1" ]]; then + if [[ -f "${configPath}09_routing.json" ]]; then + jq ".routing.rules[]|select(.outboundTag==\"$1\")" "${configPath}09_routing.json" + + echoContent yellow "# Notes\n" + echoContent yellow "1.All diversion rules set will be deleted" + echoContent skyBlue "$(jq .outbounds[0].settings.servers[0] ${configPath}socks5_outbound.json)" + + elif [[ "$1" == "socks5_outbound" && -f "${configPath}socks5_outbound.json" ]]; then + echoContent yellow "2.All outbound rules except WARP [third party] will be deleted" + echoContent yellow "1.WARP diversion [Third-party IPv4]" + echoContent skyBlue "$(jq .outbounds[0].settings.servers[0] ${configPath}socks5_outbound.json)" + fi + fi +} + +removeSocks5Routing() { + echoContent skyBlue "\nFunction 1/${totalProgress}: IPv6 offload" + echoContent red "\n==============================================================" + + echoContent yellow "2.WARP diversion [Third-party IPv6]" + echoContent yellow "3.IPv6 offload" + echoContent yellow "4.Any door diversion" + read -r -p "Select:" unInstallSocks5RoutingStatus + if [[ "${unInstallSocks5RoutingStatus}" == "1" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + removeXrayOutbound socks5_outbound + unInstallRouting socks5_outbound outboundTag + + addXrayOutbound z_direct_outbound + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxConfig socks5_outbound + removeSingBoxConfig socks5_01_outbound_route + addSingBoxOutbound 01_direct_outbound + fi + + elif [[ "${unInstallSocks5RoutingStatus}" == "2" ]]; then + + removeSingBoxConfig 20_socks5_inbounds + removeSingBoxConfig socks5_02_inbound_route + removeSingBoxConfig sniff_socks5_inbound + removeSingBoxConfig "strategy_ipv4_only_socks5_inbound" + removeSingBoxConfig "strategy_ipv6_only_socks5_inbound" + + handleSingBox stop + elif [[ "${unInstallSocks5RoutingStatus}" == "3" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + removeXrayOutbound socks5_outbound + unInstallRouting socks5_outbound outboundTag + addXrayOutbound z_direct_outbound + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + removeSingBoxConfig socks5_outbound + removeSingBoxConfig socks5_01_outbound_route + removeSingBoxConfig 20_socks5_inbounds + removeSingBoxConfig socks5_02_inbound_route + removeSingBoxConfig sniff_socks5_inbound + removeSingBoxConfig "strategy_ipv4_only_socks5_inbound" + removeSingBoxConfig "strategy_ipv6_only_socks5_inbound" + + addSingBoxOutbound 01_direct_outbound + fi + + handleSingBox stop + else + echoContent red " ---> Available types are not installed" + exit 0 + fi + 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" + reloadCore +} +setSocks5Inbound() { + + echoContent yellow "5.DNS divert" + echoContent skyBlue "\nFunction 1/${totalProgress}: bt download management" + echo + mapfile -t result < <(initSingBoxPort "${singBoxSocks5Port}") + echoContent green "The shortcut is created successfully, you can execute [vasma] to reopen the script" + echoContent green " ---> Added successfully" + + echoContent yellow "6.VMess+WS+TLS offload" + read -r -p 'UUID:' socks5RoutingUUID + if [[ -z "${socks5RoutingUUID}" ]]; then + if [[ "${coreInstallType}" == "1" ]]; then + socks5RoutingUUID=$(/etc/v2ray-agent/xray/xray uuid) + elif [[ -n "${singBoxConfigPath}" ]]; then + socks5RoutingUUID=$(/etc/v2ray-agent/sing-box/sing-box generate uuid) + fi + fi + echo + echoContent green " ---> IPv6 global outbound setting successful" + echoContent green " ---> Abandon settings" + + echoContent yellow "7.SNI reverse proxy offload" + echoContent yellow "1.Any door floor machine unlocks streaming media" + echoContent yellow "2.DNS unlock streaming media" + echoContent yellow "2.IPv6" + + read -r -p 'IP type:' socks5InboundDomainStrategyStatus + local domainStrategy= + if [[ -z "${socks5InboundDomainStrategyStatus}" || "${socks5InboundDomainStrategyStatus}" == "1" ]]; then + domainStrategy="ipv4_only" + elif [[ "${socks5InboundDomainStrategyStatus}" == "2" ]]; then + domainStrategy="ipv6_only" + else + echoContent red " ---> Wrong selection" + exit 0 + fi + cat </etc/v2ray-agent/sing-box/conf/config/20_socks5_inbounds.json +{ + "inbounds":[ + { + "type": "socks", + "listen":"::", + "listen_port":${result[-1]}, + "tag":"socks5_inbound", + "users":[ + { + "username": "${socks5RoutingUUID}", + "password": "${socks5RoutingUUID}" + } + ] + } + ] +} +EOF + setStrategyRouting socks5_inbound "${domainStrategy}" +} + +initSingBoxRules() { + local domainRules=[] + local ruleSet=[] + while read -r line; do + local normalizedLine= + normalizedLine=$(echo "${line}" | tr '[:upper:]' '[:lower:]' | sed 's/^[[:space:]]*//;s/[[:space:]]*$//') + if isDomainFormat "${normalizedLine}"; then + local escapedDomain= + escapedDomain=${normalizedLine//./\\.} + domainRules=$(echo "${domainRules}" | jq -r --arg reg ".*${escapedDomain}.*" '. += [$reg]') + else + local matchedRuleName + matchedRuleName=$(getDLCGeositeName "${normalizedLine}" "/etc/v2ray-agent/sing-box") + + if [[ -n "${matchedRuleName}" ]]; then + ruleSet=$(echo "${ruleSet}" | jq -r ". += [{\"tag\":\"${matchedRuleName}_$2\",\"type\":\"remote\",\"format\":\"binary\",\"url\":\"https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-${matchedRuleName}.srs\",\"http_client\":\"rule_set_http\"}]") + else + domainRules=$(echo "${domainRules}" | jq -r --arg reg "^([a-zA-Z0-9_-]+\\.)*${normalizedLine//./\\.}" '. += [$reg]') + fi + fi + done < <(echo "$1" | tr ',' '\n' | grep -v '^$' | sort -n | uniq | paste -sd ',' | tr ',' '\n') + echo "{ \"domainRules\":${domainRules},\"ruleSet\":${ruleSet}}" +} + +setSocks5InboundRouting() { + + singBoxConfigPath=/etc/v2ray-agent/sing-box/conf/config/ + + if [[ "$1" == "addRules" && ! -f "${singBoxConfigPath}socks5_02_inbound_route.json" && ! -f "${configPath}09_routing.json" ]]; then + echoContent red " ---> UUID cannot be repeated" + echoContent red " ---> email cannot be repeated" + exit 0 + fi + local socks5InboundRoutingIPs= + if [[ "$1" == "addRules" ]]; then + socks5InboundRoutingIPs=$(jq .route.rules[0].source_ip_cidr "${singBoxConfigPath}socks5_02_inbound_route.json") + else + echoContent red "==============================================================" + echoContent skyBlue "\nProgress$1/${totalProgress}: Domain name blacklist" + read -r -p "IP:" socks5InboundRoutingIPs + + if [[ -z "${socks5InboundRoutingIPs}" ]]; then + echoContent red " ---> Incorrect input, please re-enter" + exit 0 + fi + socks5InboundRoutingIPs=$(echo "\"${socks5InboundRoutingIPs}"\" | jq -c '.|split(",")') + fi + + echoContent red "==============================================================" + echoContent skyBlue "\nProgress$1/${totalProgress}: WARP offload" + echoContent yellow "3.VMess+WS+TLS to unlock streaming media" + 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" + + read -r -p "Allow all websites? Select [y/n]:" socks5InboundRoutingDomainStatus + if [[ "${socks5InboundRoutingDomainStatus}" == "y" ]]; then + addSingBoxRouteRule "01_direct_outbound" "" "socks5_02_inbound_route" + local route= + route=$(jq ".route.rules[0].inbound = [\"socks5_inbound\"]" "${singBoxConfigPath}socks5_02_inbound_route.json") + route=$(echo "${route}" | jq ".route.rules[0].source_ip_cidr=${socks5InboundRoutingIPs}") + echo "${route}" | jq . >"${singBoxConfigPath}socks5_02_inbound_route.json" + + addSingBoxOutbound block + addSingBoxOutbound "01_direct_outbound" + else + echoContent yellow "2.Add inbound" + read -r -p "Domain:" socks5InboundRoutingDomain + if [[ -z "${socks5InboundRoutingDomain}" ]]; then + echoContent red " ---> Incorrect input, please re-enter" + exit 0 + fi + addSingBoxRouteRule "01_direct_outbound" "${socks5InboundRoutingDomain}" "socks5_02_inbound_route" + local route= + route=$(jq ".route.rules[0].inbound = [\"socks5_inbound\"]" "${singBoxConfigPath}socks5_02_inbound_route.json") + route=$(echo "${route}" | jq ".route.rules[0].source_ip_cidr=${socks5InboundRoutingIPs}") + echo "${route}" | jq . >"${singBoxConfigPath}socks5_02_inbound_route.json" + + addSingBoxOutbound block + addSingBoxOutbound "01_direct_outbound" + fi + +} + +setSniffRouting() { + local singBoxDNSConfigPath="/etc/v2ray-agent/sing-box/conf/config/dns.json" + if [[ -f "${singBoxDNSConfigPath}" ]]; then + jq ' + .dns.servers = (.dns.servers // []) + | if any(.dns.servers[]?; .tag == "local") then . + elif any(.dns.servers[]?; .type == "local" and ((.tag // "") == "")) then + .dns.servers |= map(if .type == "local" and ((.tag // "") == "") then .tag = "local" else . end) + else + .dns.servers += [{"tag": "local", "type": "local"}] + end + ' "${singBoxDNSConfigPath}" >"${singBoxDNSConfigPath}.tmp" && mv "${singBoxDNSConfigPath}.tmp" "${singBoxDNSConfigPath}" + else + cat <"${singBoxDNSConfigPath}" +{ + "dns": { + "servers": [ + { + "tag": "local", + "type": "local" + } + ] + } +} +EOF + fi + + cat <"/etc/v2ray-agent/sing-box/conf/config/sniff.json" +{ + "route":{ + "default_domain_resolver": "local", + "rules":[ + { + "action": "sniff", + "timeout": "1s" + }, + { + "protocol": "dns", + "action": "hijack-dns" + } + ] + } +} +EOF +} + +setStrategyRouting() { + local tag=$1 + local strategy=$2 + cat <"/etc/v2ray-agent/sing-box/conf/config/strategy_${strategy}_${tag}.json" +{ + "route":{ + "rules":[ + { + "inbound": "${tag}", + "action": "resolve", + "strategy": "${strategy}" + } + ] + } +} +EOF +} +setSocks5Outbound() { + + echoContent yellow "3.Uninstall" + echo + read -r -p "Enter the landing server IP address:" socks5RoutingOutboundIP + if [[ -z "${socks5RoutingOutboundIP}" ]]; then + echoContent red " ---> Wrong selection" + exit 0 + fi + echo + read -r -p "Enter the landing server port:" socks5RoutingOutboundPort + if [[ -z "${socks5RoutingOutboundPort}" ]]; then + echoContent red " ---> Wrong selection" + exit 0 + fi + echo + read -r -p "Enter username:" socks5RoutingOutboundUserName + if [[ -z "${socks5RoutingOutboundUserName}" ]]; then + echoContent red "\n================================================ =================" + exit 0 + fi + echo + read -r -p "Enter password:" socks5RoutingOutboundPassword + if [[ -z "${socks5RoutingOutboundPassword}" ]]; then + echoContent red "================================================== ===============" + exit 0 + fi + echo + if [[ -n "${singBoxConfigPath}" ]]; then + cat <"${singBoxConfigPath}socks5_outbound.json" +{ + "outbounds":[ + { + "type": "socks", + "tag":"socks5_outbound", + "server": "${socks5RoutingOutboundIP}", + "server_port": ${socks5RoutingOutboundPort}, + "version": "5", + "username":"${socks5RoutingOutboundUserName}", + "password":"${socks5RoutingOutboundPassword}" + } + ] +} +EOF + fi + if [[ "${coreInstallType}" == "1" ]]; then + addXrayOutbound socks5_outbound + fi +} + +setSocks5OutboundRouting() { + + if [[ "$1" == "addRules" && ! -f "${singBoxConfigPath}socks5_01_outbound_route.json" && ! -f "${configPath}09_routing.json" ]]; then + echoContent red " ---> The installation directory is not detected, please execute the script to install the content" + exit 0 + fi + + echoContent red "==============================================================" + echoContent skyBlue "\nProgress$1/${totalProgress}: WARP offload [third party]" + 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" + echoContent yellow "Input example:netflix,openai\n" + read -r -p "Domain:" socks5RoutingOutboundDomain + if [[ -z "${socks5RoutingOutboundDomain}" ]]; then + echoContent red "\n================================================ =================" + exit 0 + fi + addSingBoxRouteRule "socks5_outbound" "${socks5RoutingOutboundDomain}" "socks5_01_outbound_route" + addSingBoxOutbound "01_direct_outbound" + + if [[ "${coreInstallType}" == "1" ]]; then + + unInstallRouting "socks5_outbound" "outboundTag" + local domainRules=[] + while read -r line; do + if echo "${routingRule}" | grep -q "${line}"; then + echoContent yellow "Input example:netflix,openai\n" + else + local matchedRuleValue + matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray") + domainRules=$(echo "${domainRules}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]') + fi + done < <(echo "${socks5RoutingOutboundDomain}" | tr ',' '\n') + if [[ ! -f "${configPath}09_routing.json" ]]; then + cat <${configPath}09_routing.json +{ + "routing":{ + "rules": [] + } +} +EOF + fi + routing=$(jq -r ".routing.rules += [{\"type\": \"field\",\"domain\": ${domainRules},\"outboundTag\": \"socks5_outbound\"}]" ${configPath}09_routing.json) + echo "${routing}" | jq . >${configPath}09_routing.json + fi +} # 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 + echoContent red "==============================================================" + echoContent yellow "ip entry example:1.1.1.1,1.1.1.2" + read -r -p "Please enter the domain name according to the above example:" domainList if [[ -z ${domainList} ]]; then - echoContent red " ---> Domain name cannot be empty" + echoContent red "================================================== ===============" setVMessWSRoutingOutbounds fi if [[ -n "${setVMessWSTLSAddress}" ]]; then - - unInstallOutboundsVMess-out + removeXrayOutbound VMess-out echo read -r -p "Please enter the port of VMess+WS+TLS:" setVMessWSTLSPort echo if [[ -z "${setVMessWSTLSPort}" ]]; then - echoContent red " ---> Port cannot be empty" + echoContent red " ---> does not support ipv6" fi read -r -p "Please enter the UUID of VMess+WS+TLS:" setVMessWSTLSUUID echo if [[ -z "${setVMessWSTLSUUID}" ]]; then - echoContent red " ---> UUID cannot be empty" + echoContent red " ---> Not installed, please use script to install" 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" + echoContent red "\n================================================ ============ =====" 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) - - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - - addInstallRouting VMess-out outboundTag "${domainList}" + addXrayOutbound "VMess-out" + addXrayRouting VMess-out outboundTag "${domainList}" reloadCore - echoContent green " ---> Added shunt successfully" + echoContent green " ---> IPv6 offload uninstall successful" exit 0 fi - echoContent red " ---> The address cannot be empty" + echoContent red "================================================== ===============" setVMessWSRoutingOutbounds } -# 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 " ---> Domain name cannot be empty" - setDokodemoDoorRoutingOutbounds - fi - - if [[ -n "${setIP}" ]]; then - - unInstallOutbounds dokodemoDoor-80 - unInstallOutbounds dokodemoDoor-443 - - addInstallRouting dokodemoDoor-80 outboundTag "${domainList}" - addInstallRouting dokodemoDoor-443 outboundTag "${domainList}" - - 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) - - echo "${outbounds}" | jq . >${configPath}10_ipv4_outbounds.json - - reloadCore - echoContent green " ---> Add any door to divert successfully" - exit 0 - fi - echoContent red " ---> ip cannot be empty" -} - -# Set any door diversion [inbound] -setDokodemoDoorRoutingInbounds() { - - 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_dokodemoDoor_inbounds.json -{ - "inbounds": [ - { - "listen": "0.0.0.0", - "port": 22387, - "protocol": "dokodemo-door", - "settings": { - "address": "0.0.0.0", - "port": 80, - "network": "tcp", - "followRedirect": false - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "http" - ] - }, - "tag": "dokodemoDoor-80" - }, - { - "listen": "0.0.0.0", - "port": 22388, - "protocol": "dokodemo-door", - "settings": { - "address": "0.0.0.0", - "port": 443, - "network": "tcp", - "followRedirect": false - }, - "sniffing": { - "enabled": true, - "destOverride": [ - "tls" - ] - }, - "tag": "dokodemoDoor-443" - } - ] -} -EOF - local domains= - domains=[] - while read -r line; do - local matchedRuleValue - matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray") - domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]') - 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 -{ - "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 - - fi - - reloadCore - echoContent green " ---> Added landing machine inbound traffic successfully" - exit 0 - fi - echoContent red " ---> ip cannot be empty" -} - -# Remove any door shunt -removeDokodemoDoorRouting() { - - unInstallOutbounds dokodemoDoor-80 - unInstallOutbounds dokodemoDoor-443 - - unInstallRouting dokodemoDoor-80 inboundTag - unInstallRouting dokodemoDoor-443 inboundTag - - unInstallRouting dokodemoDoor-80 outboundTag - unInstallRouting dokodemoDoor-443 outboundTag - - rm -rf ${configPath}01_dokodemoDoor_inbounds.json - - reloadCore - echoContent green " ---> Uninstall successful" -} - # Remove VMess+WS+TLS shunt removeVMessWSRouting() { - unInstallOutbounds VMess-out - + removeXrayOutbound VMess-out unInstallRouting VMess-out outboundTag reloadCore - echoContent green " ---> Uninstall successful" + echoContent green " ---> BT download disabled successfully" } # Restart core @@ -6565,19 +8020,10 @@ reloadCore() { 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 + if echo "${currentInstallProtocolType}" | grep -q ",20," || [[ "${coreInstallType}" == "2" || -n "${singBoxConfigPath}" ]]; then + handleSingBox stop + handleSingBox start fi } @@ -6585,17 +8031,17 @@ reloadCore() { dnsRouting() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" + echoContent red "================================================== ===============" menu exit 0 fi - echoContent skyBlue "\nFunction 1/${totalProgress}: DNS offloading" - echoContent red "\n================================================ =================" + echoContent skyBlue "\nFunction 1/${totalProgress}: Diversion tool" + echoContent red "\n==============================================================" + echoContent yellow "The domain name below must be consistent with the outbound vps" + echoContent yellow "Example of domain name entry: netflix,openai\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 @@ -6612,17 +8058,18 @@ dnsRouting() { sniRouting() { if [[ -z "${configPath}" ]]; then - echoContent red " ---> Not installed, please use script to install" + echoContent red "================================================== ===============" 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 skyBlue "\nFunction 1/${totalProgress}: Streaming Media Toolbox" + echoContent red "\n==============================================================" echoContent yellow "1.Add" echoContent yellow "2.Uninstall" + 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" read -r -p "Please select:" selectType case ${selectType} in @@ -6638,17 +8085,17 @@ sniRouting() { 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 + echoContent red "==============================================================" - if [[ -n "${domainList}" ]]; then + if [[ "${coreInstallType}" == 1 ]]; then + echoContent yellow "2.Uninstall" + read -r -p "Enter domains using the example above:" xrayDomainList local hosts={} while read -r domain; do local matchedRuleValue matchedRuleValue=$(getDLCMatchedRuleValue "${domain}" "/etc/v2ray-agent/xray") hosts=$(echo "${hosts}" | jq -r --arg key "${matchedRuleValue}" --arg value "${setSNIP}" '. + {($key):$value}') - done < <(echo "${domainList}" | tr ',' '\n') + done < <(echo "${xrayDomainList}" | tr ',' '\n') cat <${configPath}11_dns.json { "dns": { @@ -6660,44 +8107,38 @@ setUnlockSNI() { } } EOF - echoContent red " ---> SNI reverse proxy distribution successful" - reloadCore - else - echoContent red " ---> Domain name cannot be empty" fi - + if [[ -n "${singBoxConfigPath}" ]]; then + echoContent yellow "Input example: netflix, disney, hulu" + read -r -p "Enter domains using the example above:" singboxDomainList + addSingBoxDNSConfig "${setSNIP}" "${singboxDomainList}" "predefined" + fi + echoContent yellow "Input example: netflix, disney, hulu" + reloadCore else - - echoContent red " ---> SNI IP cannot be empty" + echoContent red " ---> Wrong selection" fi exit 0 } -# Set dns -setUnlockDNS() { - 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 - domainList="netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu" - fi - if [[ -n "${domainList}" ]]; then - local domains=[] - while read -r line; do - local matchedRuleValue - matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray") - domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]') - done < <(echo "${domainList}" | tr ',' '\n') - cat <${configPath}11_dns.json +addXrayDNSConfig() { + local ip=$1 + local domainList=$2 + local domains=[] + while read -r line; do + local matchedRuleValue + matchedRuleValue=$(getDLCMatchedRuleValue "${line}" "/etc/v2ray-agent/xray") + domains=$(echo "${domains}" | jq -r --arg rule "${matchedRuleValue}" '. += [$rule]') + done < <(echo "${domainList}" | tr ',' '\n') + + if [[ "${coreInstallType}" == "1" ]]; then + + cat <${configPath}11_dns.json { "dns": { "servers": [ { - "address": "${setDNS}", + "address": "${ip}", "port": 53, "domains": ${domains} }, @@ -6706,22 +8147,119 @@ setUnlockDNS() { } } EOF + fi +} + +addSingBoxDNSConfig() { + local ip=$1 + local domainList=$2 + local actionType=$3 + + local rules= + rules=$(initSingBoxRules "${domainList}" "dns") + local domainRules= + domainRules=$(echo "${rules}" | jq .domainRules) + + local ruleSet= + ruleSet=$(echo "${rules}" | jq .ruleSet) + + local ruleSetTag=[] + if [[ "$(echo "${ruleSet}" | jq '.|length')" != "0" ]]; then + ruleSetTag=$(echo "${ruleSet}" | jq '.|map(.tag)') + fi + if [[ -n "${singBoxConfigPath}" ]]; then + if [[ "${actionType}" == "predefined" ]]; then + local predefined={} + while read -r line; do + predefined=$(echo "${predefined}" | jq ".\"${line}\"=\"${ip}\"") + done < <(echo "${domainList}" | tr ',' '\n' | grep -v '^$' | sort -n | uniq | paste -sd ',' | tr ',' '\n') + + cat <"${singBoxConfigPath}dns.json" +{ + "dns": { + "servers": [ + { + "tag": "local", + "type": "local" + }, + { + "tag": "hosts", + "type": "hosts", + "predefined": ${predefined} + } + ], + "rules": [ + { + "domain_regex":${domainRules}, + "server":"hosts" + } + ] + } +} +EOF + else + cat <"${singBoxConfigPath}dns.json" +{ + "dns": { + "servers": [ + { + "tag": "local", + "type": "local" + }, + { + "tag": "dnsRouting", + "type": "udp", + "server": "${ip}" + } + ], + "rules": [ + { + "rule_set": ${ruleSetTag}, + "domain_regex": ${domainRules}, + "server":"dnsRouting" + } + ] + }, + "route":{ + "rule_set":${ruleSet} + } +} +EOF + fi + fi +} +# Set dns +setUnlockDNS() { + read -r -p "Please enter the diverted DNS:" setDNS + if [[ -n ${setDNS} ]]; then + echoContent red "==============================================================" + echoContent yellow "Please enter 1 for the default scheme. The default scheme includes the following content" + read -r -p "Please enter the domain name according to the above example:" domainList + + if [[ "${coreInstallType}" == "1" ]]; then + addXrayDNSConfig "${setDNS}" "${domainList}" + fi + + if [[ -n "${singBoxConfigPath}" ]]; then + addSingBoxOutbound 01_direct_outbound + addSingBoxDNSConfig "${setDNS}" "${domainList}" fi reloadCore + echoContent yellow "netflix,bahamut,hulu,hbo,disney,bbc,4chan,fox,abema,dmm,niconico,pixiv,bilibili,viu" 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" + echoContent red " ---> Not installed, please use script to install" fi exit 0 } # Remove DNS offloading removeUnlockDNS() { - cat <${configPath}11_dns.json + if [[ "${coreInstallType}" == "1" && -f "${configPath}11_dns.json" ]]; then + cat <${configPath}11_dns.json { "dns": { "servers": [ @@ -6730,242 +8268,297 @@ removeUnlockDNS() { } } EOF + fi + + if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}dns.json" ]]; then + cat <${singBoxConfigPath}dns.json +{ + "dns": { + "servers":[ + { + "tag":"local", + "type":"local" + } + ] + } +} +EOF + fi + reloadCore - echoContent green " ---> Uninstall successful" + echoContent green " ---> BT download opened successfully" exit 0 } # Remove SNI shunt removeUnlockSNI() { - cat <${configPath}11_dns.json + if [[ "${coreInstallType}" == 1 ]]; then + cat <${configPath}11_dns.json { - "dns": { - "servers": [ - "localhost" - ] - } + "dns": { + "servers": [ + "localhost" + ] + } } EOF - reloadCore + fi - echoContent green " ---> Uninstall successful" + if [[ "${coreInstallType}" == "2" && -f "${singBoxConfigPath}dns.json" ]]; then + cat <${singBoxConfigPath}dns.json +{ + "dns": { + "servers":[ + { + "type":"local" + } + ] + } +} +EOF + fi + + reloadCore + echoContent green " ---> Added successfully" exit 0 } -# v2ray-core personalized installation -customV2RayInstall() { - echoContent skyBlue "\n========================Personalized installation================== ==========" +customSingBoxInstall() { + echoContent skyBlue "\nFunction 1/${totalProgress}: any door diversion" + echoContent yellow "0.VLESS+Vision+TCP" + echoContent yellow "2.After uninstalling dns unlocking, modify the local [/etc/resolv.conf] DNS settings and restart vps\n" 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 + echoContent yellow "6.Hysteria2" + echoContent yellow "7.VLESS+Reality+Vision" + echoContent yellow "8.VLESS+Reality+gRPC" + echoContent yellow "9.Tuic" + echoContent yellow "10.Naive" + echoContent yellow "11.VMess+TLS+HTTPUpgrade" + echoContent yellow "13.anytls" - # Install V2Ray - installV2Ray 8 - installV2RayService 9 - initV2RayConfig custom 10 + read -r -p "Please select [multiple selection], [for example: 123]:" selectCustomInstallType + echoContent skyBlue "--------------------------------------------------------------" + if echo "${selectCustomInstallType}" | grep -q ","; then + echoContent red "\n================================================ =================" + exit 0 + fi + if [[ "${selectCustomInstallType}" != "10" ]] && [[ "${selectCustomInstallType}" != "11" ]] && [[ "${selectCustomInstallType}" != "13" ]] && ((${#selectCustomInstallType} >= 2)) && ! echo "${selectCustomInstallType}" | grep -q ","; then + echoContent red "================================================== ===============" + exit 0 + fi + if [[ "${selectCustomInstallType: -1}" != "," ]]; then + selectCustomInstallType="${selectCustomInstallType}," + fi + if [[ "${selectCustomInstallType:0:1}" != "," ]]; then + selectCustomInstallType=",${selectCustomInstallType}," + fi + + if [[ "${selectCustomInstallType//,/}" =~ ^[0-9]+$ ]]; then + readLastInstallationConfig + unInstallSubscribe + totalProgress=9 + installTools 1 + if echo "${selectCustomInstallType}" | grep -q -E ",0,|,1,|,3,|,4,|,6,|,9,|,10,|,11,|,13,"; then + # Apply for tls + initTLSNginxConfig 2 + # handleNginx start + installTLS 3 + handleNginx stop + fi + + installSingBox 4 + installSingBoxService 5 + initSingBoxConfig custom 6 cleanUp xrayDel - installCronTLS 14 - handleV2Ray stop - handleV2Ray start - # Generate account - checkGFWStatue 15 - showAccounts 16 + installCronTLS 7 + handleSingBox stop + handleSingBox start + handleNginx stop + handleNginx start + checkGFWStatue 8 + showAccounts 9 else - echoContent red " ---> Input is illegal" - customV2RayInstall + echoContent red " ---> Wrong selection" + customSingBoxInstall fi } +installXrayReality() { + selectCustomInstallType=",7," + readLastInstallationConfig + unInstallSubscribe + totalProgress=6 + installTools 1 + + handleNginx stop + + installXray 2 false + installXrayService 3 + initXrayConfig custom 4 + cleanUp singBoxDel + + handleXray stop + handleXray start + checkGFWStatue 5 + showAccounts 6 +} +installSingBoxReality() { + + selectCustomInstallType=",7," + readLastInstallationConfig + unInstallSubscribe + totalProgress=6 + installTools 1 + + installSingBox 2 + installSingBoxService 3 + initSingBoxConfig custom 4 + cleanUp xrayDel + handleSingBox stop + handleSingBox start + checkGFWStatue 5 + showAccounts 6 +} # Xray-core personalized installation customXrayInstall() { - 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 skyBlue "\nFunction 1/${totalProgress}: VMess+WS+TLS offload" 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 "VLESS is prefixed and 0 is installed by default. If you only need to install 0, just select 0" # echoContent yellow "8.VLESS+Reality+gRPC" + echoContent yellow "0.VLESS+TLS_Vision+TCP[recommended]" 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 - - if ! echo "${selectCustomInstallType}" | grep -q "0"; then - selectCustomInstallType="0${selectCustomInstallType}" + echoContent skyBlue "--------------------------------------------------------------" + if echo "${selectCustomInstallType}" | grep -q ","; then + echoContent red " ---> Not installed, please use script to install" + exit 0 + fi + if [[ "${selectCustomInstallType}" != "12" ]] && ((${#selectCustomInstallType} >= 2)) && ! echo "${selectCustomInstallType}" | grep -q ","; then + echoContent red "\n================================================ =================" + exit 0 + fi + if echo "${selectCustomInstallType}" | grep -qE '^(7|7,12|12)$'; then + selectCustomInstallType=",${selectCustomInstallType}," + else + if ! echo "${selectCustomInstallType}" | grep -q "0,"; then + selectCustomInstallType=",0,${selectCustomInstallType}," + else + selectCustomInstallType=",${selectCustomInstallType}," fi - cleanUp v2rayClean - checkBTPanel + fi + if [[ "${selectCustomInstallType:0:1}" != "," ]]; then + selectCustomInstallType=",${selectCustomInstallType}," + fi + if [[ "${selectCustomInstallType//,/}" =~ ^[0-7]+$ ]]; then + readLastInstallationConfig + unInstallSubscribe + # checkBTPanel + # check1Panel totalProgress=12 installTools 1 if [[ -n "${btDomain}" ]]; then - echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" + echoContent skyBlue "\nFunction 1/${totalProgress}: Add inbound at any door" handleXray stop - customPortFunction + if [[ "${selectCustomInstallType}" != ",7," ]]; then + customPortFunction + fi else + if ! echo "${selectCustomInstallType}" | grep -qE '^(,7,|,7,12,|,12,)$'; then # Apply for tls - initTLSNginxConfig 2 - handleXray stop - # handleNginx start - installTLS 3 + initTLSNginxConfig 2 + handleXray stop + installTLS 3 + else + echoContent skyBlue "\nFunction 1/${totalProgress}: DNS offloading" + fi fi 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 + if echo "${selectCustomInstallType}" | grep -qE ",1,|,2,|,3,|,5,|,12,"; 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 + echoContent skyBlue "\nFunction 1/${totalProgress}: SNI reverse proxy offload" else nginxBlog 6 fi - updateRedirectNginxConf - handleNginx start + if ! echo "${selectCustomInstallType}" | grep -qE '^(,7,|,7,12,|,12,)$'; then + updateRedirectNginxConf + handleNginx start + fi # Install Xray installXray 7 false installXrayService 8 initXrayConfig custom 9 - cleanUp v2rayDel + cleanUp singBoxDel + if ! echo "${selectCustomInstallType}" | grep -qE '^(,7,|,7,12,|,12,)$'; then + installCronTLS 10 + fi - installCronTLS 10 handleXray stop handleXray start # Generate account checkGFWStatue 11 showAccounts 12 else - echoContent red " ---> Input is illegal" + echoContent red "================================================== ===============" customXrayInstall fi } # Select core installation---v2ray-core, xray-core selectCoreInstall() { - echoContent skyBlue "\nFunction 1/${totalProgress}: Select core installation" - echoContent red "\n================================================ =================" + echoContent skyBlue "\n========================Personalized installation================== ==========" + echoContent red "\n==============================================================" echoContent yellow "1.Xray-core" - echoContent yellow "2.v2ray-core" - echoContent red "================================================== ===============" + echoContent yellow "2.sing-box" + echoContent red "==============================================================" read -r -p "Please select:" selectCoreType case ${selectCoreType} in 1) - if [[ "${selectInstallType}" == "2" ]]; then - customXrayInstall - else + if [[ "${selectInstallType}" == "1" ]]; then xrayCoreInstall + elif [[ "${selectInstallType}" == "2" ]]; then + customXrayInstall + elif [[ "${selectInstallType}" == "3" ]]; then + installXrayReality 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 + if [[ "${selectInstallType}" == "1" ]]; then + singBoxInstall + elif [[ "${selectInstallType}" == "2" ]]; then + customSingBoxInstall + elif [[ "${selectInstallType}" == "3" ]]; then + installSingBoxReality fi ;; *) - echoContent red ' ---> Wrong selection, select again' + echoContent red "================================================== ===============" selectCoreInstall ;; esac } -# v2ray-core installation -v2rayCoreInstall() { - cleanUp xrayClean - checkBTPanel - selectCustomInstallType= - totalProgress=13 - installTools 2 - # Apply for tls - initTLSNginxConfig 3 - - handleV2Ray stop - handleNginx start - - 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 installation xrayCoreInstall() { - cleanUp v2rayClean - checkBTPanel + readLastInstallationConfig + unInstallSubscribe + # checkBTPanel + # check1Panel selectCustomInstallType= - totalProgress=13 + totalProgress=12 installTools 2 if [[ -n "${btDomain}" ]]; then - echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" + echoContent skyBlue "------------------------------------------------- ---------------" handleXray stop customPortFunction else @@ -6979,24 +8572,17 @@ xrayCoreInstall() { handleNginx stop randomPathFunction 5 + # Install Xray installXray 6 false installXrayService 7 - customCDNIP 8 - initXrayConfig all 9 - cleanUp v2rayDel - installCronTLS 10 + initXrayConfig all 8 + cleanUp singBoxDel + installCronTLS 9 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 + echoContent skyBlue "\n========================Personalized installation================== ==========" else - nginxBlog 11 + nginxBlog 10 fi updateRedirectNginxConf handleXray stop @@ -7004,79 +8590,64 @@ xrayCoreInstall() { handleXray start handleNginx start - # Generate account - checkGFWStatue 12 - showAccounts 13 + checkGFWStatue 11 + showAccounts 12 } -#HysteriaInstallation -hysteriaCoreInstall() { - 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 -unInstallHysteriaCore() { +singBoxInstall() { + readLastInstallationConfig + unInstallSubscribe + # checkBTPanel + # check1Panel + selectCustomInstallType= + totalProgress=8 + installTools 2 - if [[ -z "${hysteriaConfigPath}" ]]; then - echoContent red "\n ---> not installed" - exit 0 + if [[ -n "${btDomain}" ]]; then + echoContent skyBlue "------------------------------------------------- --------- ------" + handleXray stop + customPortFunction + else + initTLSNginxConfig 3 + handleXray stop + installTLS 4 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() { + handleNginx stop - 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" + installSingBox 5 + installSingBoxService 6 + initSingBoxConfig all 7 + + cleanUp xrayDel + installCronTLS 8 + + handleSingBox stop + handleSingBox start + handleNginx stop + handleNginx start + showAccounts 9 } # Core Management coreVersionManageMenu() { if [[ -z "${coreInstallType}" ]]; then - echoContent red "\n >The installation directory is not detected, please execute the script to install the content" + echoContent red " ---> ip cannot be empty" menu exit 0 fi - if [[ "${coreInstallType}" == "1" ]]; then + echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" + echoContent red "\n==============================================================" + echoContent yellow "1.Xray-core" + echoContent yellow "2.sing-box" + echoContent red "==============================================================" + read -r -p "Enter selection:" selectCore + + if [[ "${selectCore}" == "1" ]]; then xrayVersionManageMenu 1 - elif [[ "${coreInstallType}" == "2" ]]; then - v2rayCoreVersion= - v2rayVersionManageMenu 1 + elif [[ "${selectCore}" == "2" ]]; then + singBoxVersionManageMenu 1 fi } # Scheduled task check @@ -7092,21 +8663,21 @@ cronFunction() { } #Account management manageAccount() { - echoContent skyBlue "\nFunction 1/${totalProgress}: Account Management" + echoContent skyBlue "\nProgress 6/${totalProgress}: Pagoda panel detected, skipping disguised website" if [[ -z "${configPath}" ]]; then - echoContent red " ---> not installed" + echoContent red " ---> domain cannot be empty" 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 "================================================== ===============" + echoContent red "\n==============================================================" + 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 "1.Xray-core" + echoContent red "==============================================================" read -r -p "Please enter:" manageAccountStatus if [[ "${manageAccountStatus}" == "1" ]]; then showAccounts 1 @@ -7115,7 +8686,7 @@ manageAccount() { elif [[ "${manageAccountStatus}" == "3" ]]; then addSubscribeMenu 1 elif [[ "${manageAccountStatus}" == "4" ]]; then - addUserXray + addUser elif [[ "${manageAccountStatus}" == "5" ]]; then removeUser else @@ -7123,76 +8694,155 @@ manageAccount() { fi } +installSubscribe() { + readNginxSubscribe + local nginxSubscribeListen= + local nginxSubscribeSSL= + local serverName= + local SSLType= + local listenIPv6= + if [[ -z "${subscribePort}" ]]; then + + nginxVersion=$(nginx -v 2>&1) + + if echo "${nginxVersion}" | grep -q "not found" || [[ -z "${nginxVersion}" ]]; then + echoContent yellow "2.v2ray-core" + read -r -p "Install [y/n]?" installNginxStatus + if [[ "${installNginxStatus}" == "y" ]]; then + installNginxTools + else + echoContent red " ---> Parameter error" + exit 0 + fi + fi + echoContent yellow "# Only delete VLESS Reality related configurations, other content will not be deleted." + + mapfile -t result < <(initSingBoxPort "${subscribePort}") + echo + echoContent yellow "# If you need to uninstall other content, please uninstall the script function" + nginxBlog + echo + local httpSubscribeStatus= + + if ! echo "${selectCustomInstallType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,|,11,|,13," && ! echo "${currentInstallProtocolType}" | grep -qE ",0,|,1,|,2,|,3,|,4,|,5,|,6,|,9,|,10,|,11,|,13," && [[ -z "${domain}" ]]; then + httpSubscribeStatus=true + fi + + if [[ "${httpSubscribeStatus}" == "true" ]]; then + + echoContent yellow "# You can customize email and uuid when adding a single user" + echo + read -r -p "Use HTTP subscription [y/n]?" addNginxSubscribeStatus + echo + if [[ "${addNginxSubscribeStatus}" != "y" ]]; then + echoContent yellow "# If Hysteria or Tuic is installed, the account will be added to the corresponding type at the same time\n" + exit + fi + else + local subscribeServerName= + if [[ -n "${currentHost}" ]]; then + subscribeServerName="${currentHost}" + else + subscribeServerName="${domain}" + fi + + SSLType="ssl" + serverName="server_name ${subscribeServerName};" + nginxSubscribeSSL="ssl_certificate /etc/v2ray-agent/tls/${subscribeServerName}.crt;ssl_certificate_key /etc/v2ray-agent/tls/${subscribeServerName}.key;" + fi + if [[ -n "$(curl --connect-timeout 2 -s -6 http://www.cloudflare.com/cdn-cgi/trace | grep "ip" | cut -d "=" -f 2)" ]]; then + listenIPv6="listen [::]:${result[-1]} ${SSLType};" + fi + if echo "${nginxVersion}" | grep -q "1.25" && [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $3}') -gt 0 ]] || [[ $(echo "${nginxVersion}" | awk -F "[.]" '{print $2}') -gt 25 ]]; then + nginxSubscribeListen="listen ${result[-1]} ${SSLType} so_keepalive=on;http2 on;${listenIPv6}" + else + nginxSubscribeListen="listen ${result[-1]} ${SSLType} so_keepalive=on;${listenIPv6}" + fi + + cat <${nginxConfigPath}subscribe.conf +server { + ${nginxSubscribeListen} + ${serverName} + ${nginxSubscribeSSL} + ssl_protocols TLSv1.2 TLSv1.3; + ssl_ciphers TLS13_AES_128_GCM_SHA256:TLS13_AES_256_GCM_SHA384:TLS13_CHACHA20_POLY1305_SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305; + ssl_prefer_server_ciphers on; + + resolver 1.1.1.1 valid=60s; + resolver_timeout 2s; + client_max_body_size 100m; + root ${nginxStaticPath}; + location ~ ^/s/(clashMeta|default|clashMetaProfiles|sing-box|sing-box_profiles)/(.*) { + default_type 'text/plain; charset=utf-8'; + alias /etc/v2ray-agent/subscribe/\$1/\$2; + } + location / { + } +} +EOF + bootStartup nginx + handleNginx stop + handleNginx start + fi + if [[ -z $(pgrep -f "nginx") ]]; then + handleNginx start + fi +} +unInstallSubscribe() { + rm -rf ${nginxConfigPath}subscribe.conf >/dev/null 2>&1 +} + #Add subscription addSubscribeMenu() { - echoContent skyBlue "\n====================== Add other machine subscriptions==================== ===" - echoContent yellow "1.Add" - echoContent yellow "2.Remove" - echoContent red "================================================== ===============" + echoContent skyBlue "\nFunction 1/${totalProgress}: Select core installation" + echoContent yellow "1.Check account" + echoContent yellow "2.View subscription" + 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" + if [[ ! -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" ]]; then + echoContent green " ---> Domestic domain name + IP blocked successfully" + exit 0 + fi + grep -v '^$' "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" | awk '{print NR""":"$0}' + read -r -p "Select the subscription number to delete [single selection only]:" delSubscribeIndex + if [[ -z "${delSubscribeIndex}" ]]; then + echoContent green " ---> Domain blacklist/whitelist deleted successfully" + exit 0 + fi + + sed -i "$((delSubscribeIndex))d" "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" >/dev/null 2>&1 + + echoContent green " ---> Blocked IP added 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" + echoContent yellow "3.Add subscription" + echoContent yellow "4.Add user" + echoContent skyBlue "\nProgress 3/${totalProgress}: Pagoda panel detected, skip applying for TLS" read -r -p "Please enter the domain name, port and machine alias:" remoteSubscribeUrl if [[ -z "${remoteSubscribeUrl}" ]]; then - echoContent red " ---> cannot be empty" - addSubscribe + echoContent red " ---> Parameter error" + addOtherSubscribe elif ! echo "${remoteSubscribeUrl}" | grep -q ":"; then - echoContent red " ---> Rule is illegal" + echoContent red "==============================================================" 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" + if [[ -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" ]] && grep -q "${remoteSubscribeUrl}" /etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl; then + echoContent red "\n================================================ =================" + exit 0 fi + echo + read -r -p "Is this an HTTP subscription? [y/n]" httpSubscribeStatus + if [[ "${httpSubscribeStatus}" == "y" ]]; then + remoteSubscribeUrl="${remoteSubscribeUrl}:http" + fi + echo "${remoteSubscribeUrl}" >>/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl + subscribe fi } # clashMeta configuration file @@ -7200,67 +8850,71 @@ 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 +log-level: debug mode: rule -log-level: info ipv6: true - -external-controller: 127.0.0.1:9090 +mixed-port: 7890 +allow-lan: true +bind-address: "*" +lan-allowed-ips: + - 0.0.0.0/0 + - ::/0 +find-process-mode: strict +external-controller: 0.0.0.0: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" + geoip: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.dat" + geosite: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geosite.dat" + mmdb: "https://fastly.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@release/geoip.metadb" +geo-auto-update: true +geo-update-interval: 24 + +external-controller-cors: + allow-private-network: true + +global-client-fingerprint: chrome profile: store-selected: true store-fake-ip: true sniffer: - enable: false + enable: true + override-destination: false sniff: + QUIC: + ports: [ 443 ] TLS: - ports: [443] + 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 + prefer-h3: false listen: 0.0.0.0:1053 ipv6: true enhanced-mode: fake-ip - fake-ip-range: 28.0.0.1/8 + fake-ip-range: 198.18.0.1/16 fake-ip-filter: - - '*' - - '+.lan' - default-nameserver: - - 223.5.5.5 + - '*.lan' + - '*.local' + - 'dns.google' + - "localhost.ptlogin2.qq.com" + use-hosts: true nameserver: - - 'tls://8.8.4.4#DNS_Proxy' - - 'tls://1.0.0.1#DNS_Proxy' + - https://1.1.1.1/dns-query + - https://8.8.8.8/dns-query + - 1.1.1.1 + - 8.8.8.8 proxy-server-nameserver: - - https://dns.alidns.com/dns-query#h3=true + - https://223.5.5.5/dns-query + - https://1.12.12.12/dns-query nameserver-policy: "geosite:cn,private": - - 223.5.5.5 - - 114.114.114.114 - - https://dns.alidns.com/dns-query#h3=true + - https://doh.pub/dns-query + - https://dns.alidns.com/dns-query proxy-providers: ${subscribeSalt}_provider: @@ -7268,32 +8922,13 @@ proxy-providers: path: ./${subscribeSalt}_provider.yaml url: ${url} interval: 3600 + proxy: DIRECT health-check: - enable: false - url: http://www.gstatic.com/generate_204 + enable: true + url: https://cp.cloudflare.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: @@ -7307,23 +8942,7 @@ proxy-groups: 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: @@ -7331,13 +8950,22 @@ proxy-groups: proxies: - ζ‰‹εŠ¨εˆ‡ζ’ - θ‡ͺεŠ¨ι€‰ζ‹© + + - name: 桁εͺ’体 + type: select + use: + - ${subscribeSalt}_provider + proxies: + - ζ‰‹εŠ¨εˆ‡ζ’ + - θ‡ͺεŠ¨ι€‰ζ‹© + - DIRECT - name: DNS_Proxy type: select use: - ${subscribeSalt}_provider proxies: - θ‡ͺεŠ¨ι€‰ζ‹© - - θŠ‚η‚Ήι€‰ζ‹© + - ζ‰‹εŠ¨εˆ‡ζ’ - DIRECT - name: Telegram @@ -7347,7 +8975,14 @@ proxy-groups: proxies: - ζ‰‹εŠ¨εˆ‡ζ’ - θ‡ͺεŠ¨ι€‰ζ‹© - + - name: Google + type: select + use: + - ${subscribeSalt}_provider + proxies: + - ζ‰‹εŠ¨εˆ‡ζ’ + - θ‡ͺεŠ¨ι€‰ζ‹© + - DIRECT - name: YouTube type: select use: @@ -7361,46 +8996,8 @@ proxy-groups: - ${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: @@ -7410,7 +9007,48 @@ proxy-groups: - ζ‰‹εŠ¨εˆ‡ζ’ - θ‡ͺεŠ¨ι€‰ζ‹© - DIRECT - - name: Google + - 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: ClaudeAI + type: select + use: + - ${subscribeSalt}_provider + proxies: + - ζ‰‹εŠ¨εˆ‡ζ’ + - θ‡ͺεŠ¨ι€‰ζ‹© + + - name: Disney + type: select + use: + - ${subscribeSalt}_provider + proxies: + - 桁εͺ’体 + - ζ‰‹εŠ¨εˆ‡ζ’ + - θ‡ͺεŠ¨ι€‰ζ‹© + - name: GitHub type: select use: - ${subscribeSalt}_provider @@ -7418,6 +9056,7 @@ proxy-groups: - ζ‰‹εŠ¨εˆ‡ζ’ - θ‡ͺεŠ¨ι€‰ζ‹© - DIRECT + - name: ε›½ε†…εͺ’体 type: select use: @@ -7430,7 +9069,6 @@ proxy-groups: - ${subscribeSalt}_provider proxies: - DIRECT - - θŠ‚η‚Ήι€‰ζ‹© - θ‡ͺεŠ¨ι€‰ζ‹© - name: 漏网之鱼 type: select @@ -7438,7 +9076,6 @@ proxy-groups: - ${subscribeSalt}_provider proxies: - DIRECT - - θŠ‚η‚Ήι€‰ζ‹© - ζ‰‹εŠ¨εˆ‡ζ’ - θ‡ͺεŠ¨ι€‰ζ‹© rule-providers: @@ -7446,127 +9083,133 @@ rule-providers: type: http behavior: classical interval: 86400 - url: https://ghproxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Lan/Lan.yaml + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/OpenAI/OpenAI.yaml path: ./ruleset/openai.yaml interval: 86400 + ClaudeAI: + type: http + behavior: classical + url: https://gh-proxy.com/https://raw.githubusercontent.com/blackmatrix7/ios_rule_script/master/rule/Clash/Claude/Claude.yaml + path: ./ruleset/claudeai.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 + url: https://gh-proxy.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 @@ -7578,6 +9221,7 @@ rules: - RULE-SET,HBO,HBO - RULE-SET,Bing,Bing - RULE-SET,OpenAI,OpenAI + - RULE-SET,ClaudeAI,ClaudeAI - RULE-SET,Disney,Disney - RULE-SET,proxy,全球代理 - RULE-SET,gfw,全球代理 @@ -7603,24 +9247,32 @@ initRandomSalt() { # Subscribe subscribe() { readInstallProtocolType + installSubscribe - if echo "${currentInstallProtocolType}" | grep -q 0 && [[ -n "${configPath}" ]]; then + readNginxSubscribe + local renewSalt=$1 + local showStatus=$2 + if [[ "${coreInstallType}" == "1" || "${coreInstallType}" == "2" ]]; then - 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" + echoContent skyBlue "\nProgress 11/${totalProgress}: Pagoda panel detected, skipping disguised website" + echoContent yellow "5.Delete user" + echoContent red "================================================== ===============" + echoContent yellow "1.Add" if [[ -f "/etc/v2ray-agent/subscribe_local/subscribeSalt" && -n $(cat "/etc/v2ray-agent/subscribe_local/subscribeSalt") ]]; then + if [[ -z "${renewSalt}" ]]; 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 + 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 + subscribeSalt=$(cat /etc/v2ray-agent/subscribe_local/subscribeSalt) fi else read -r -p "Please enter the salt value, [Enter] use random:" subscribeSalt + showStatus= fi if [[ -z "${subscribeSalt}" ]]; then @@ -7634,135 +9286,190 @@ subscribe() { rm -rf /etc/v2ray-agent/subscribe/clashMeta/* rm -rf /etc/v2ray-agent/subscribe_local/default/* rm -rf /etc/v2ray-agent/subscribe_local/clashMeta/* + rm -rf /etc/v2ray-agent/subscribe_local/sing-box/* showAccounts >/dev/null - if [[ -n $(ls /etc/v2ray-agent/subscribe_local/default/) ]]; then + if [[ -f "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl" && -n $(cat "/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl") ]]; then + if [[ -z "${renewSalt}" ]]; then + read -r -p "Other subscriptions found. Update them? [y/n]" updateOtherSubscribeStatus + else + updateOtherSubscribeStatus=y + fi + fi + local subscribePortLocal="${subscribePort}" 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}" + if [[ "${updateOtherSubscribeStatus}" == "y" ]]; then + updateRemoteSubscribe "${emailMd5}" "${email}" 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}" + if [[ -n "${subscribePortLocal}" ]]; then + if [[ "${subscribeType}" == "http" ]]; then + currentDomain="$(getPublicIP):${subscribePort}" + else + currentDomain="${currentHost}:${subscribePort}" + fi + fi + if [[ -z "${showStatus}" ]]; then + echoContent skyBlue "\nFunction 1/1: reality uninstall" + echoContent green "email:${email}\n" + echoContent yellow "url:${subscribeType}://${currentDomain}/s/default/${emailMd5}\n" + echoContent yellow "2.Remove" + if [[ "${release}" != "alpine" ]]; then + echo "${subscribeType}://${currentDomain}/s/default/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8 fi - sed -i '1i\proxies:' "/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + # clashMeta + #clashMeta + if [[ -f "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" ]]; then - 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 + cat "/etc/v2ray-agent/subscribe_local/clashMeta/${email}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + + sed -i '1i\proxies:' "/etc/v2ray-agent/subscribe/clashMeta/${emailMd5}" + + local clashProxyUrl="${subscribeType}://${currentDomain}/s/clashMeta/${emailMd5}" + clashMetaConfig "${clashProxyUrl}" "${emailMd5}" + echoContent skyBlue "\nFunction 1/${totalProgress}: Account Management" + echoContent yellow "url:${subscribeType}://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n" + echoContent yellow "#Notes:" + if [[ "${release}" != "alpine" ]]; then + echo "${subscribeType}://${currentDomain}/s/clashMetaProfiles/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8 + fi + + fi + # sing-box + if [[ -f "/etc/v2ray-agent/subscribe_local/sing-box/${email}" ]]; then + cp "/etc/v2ray-agent/subscribe_local/sing-box/${email}" "/etc/v2ray-agent/subscribe/sing-box_profiles/${emailMd5}" + + echoContent skyBlue "\n====================== Add other machine subscriptions==================== ===" + if [[ "${release}" == "alpine" ]]; then + wget -O "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" -q "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/documents/sing-box.json" + else + wget -O "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" -q "${wgetShowProgressStatus}" "https://raw.githubusercontent.com/mack-a/v2ray-agent/master/documents/sing-box.json" + fi + + jq ".outbounds=$(jq ".outbounds|map(if has(\"outbounds\") then .outbounds += $(jq ".|map(.tag)" "/etc/v2ray-agent/subscribe_local/sing-box/${email}") else . end)" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}")" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" >"/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" && mv "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" + jq ".outbounds += $(jq '.' "/etc/v2ray-agent/subscribe_local/sing-box/${email}")" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" >"/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" && mv "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}_tmp" "/etc/v2ray-agent/subscribe/sing-box/${emailMd5}" + + echoContent skyBlue "Input example: www.v2ray-agent.com:443:vps1\n" + echoContent yellow "url:${subscribeType}://${currentDomain}/s/sing-box/${emailMd5}\n" + echoContent yellow "Please read the following article carefully: https://www.v2ray-agent.com/archives/1681804748677" + if [[ "${release}" != "alpine" ]]; then + echo "${subscribeType}://${currentDomain}/s/sing-box/${emailMd5}" | qrencode -s 10 -m 1 -t UTF8 + fi + + fi + + echoContent skyBlue "--------------------------------------------------------------" + else + echoContent green " ---> Domain whitelist added successfully" fi - echoContent skyBlue "------------------------------------------------- ---------------" done fi else - echoContent red " ---> The disguise site is not installed and the subscription service cannot be used" + echoContent red "================================================== ===============" fi } # 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}') + while read -r line; do + local subscribeType= + subscribeType="https" - if [[ "${type}" == "ClashMeta" ]]; then + local serverAlias= + serverAlias=$(echo "${line}" | awk -F "[:]" '{print $3}') + + local remoteUrl= + remoteUrl=$(echo "${line}" | awk -F "[:]" '{print $1":"$2}') + + local subscribeTypeRemote= + subscribeTypeRemote=$(echo "${line}" | awk -F "[:]" '{print $4}') + + if [[ -n "${subscribeTypeRemote}" ]]; then + subscribeType="${subscribeTypeRemote}" + fi 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" + clashMetaProxies=$(curl -s "${subscribeType}://${remoteUrl}/s/clashMeta/${emailMD5}" | sed '/proxies:/d' | sed "s/\"${email}/\"${email}_${serverAlias}/g") + + if ! echo "${clashMetaProxies}" | grep -q "nginx" && [[ -n "${clashMetaProxies}" ]]; then + echo "${clashMetaProxies}" >>"/etc/v2ray-agent/subscribe/clashMeta/${emailMD5}" + echoContent green " ---> Added successfully" else - echoContent red " ---> clashMeta subscription ${remoteDomain}:${email} does not exist" + echoContent red " ---> Wrong selection" 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" + default=$(curl -s "${subscribeType}://${remoteUrl}/s/default/${emailMD5}") - echoContent green " ---> Universal subscription ${remoteDomain}:${email} updated successfully" + if ! echo "${default}" | grep -q "nginx" && [[ -n "${default}" ]]; then + default=$(echo "${default}" | base64 -d | sed "s/#${email}/#${email}_${serverAlias}/g") + echo "${default}" >>"/etc/v2ray-agent/subscribe/default/${emailMD5}" + + echoContent green " ---> WARP global outbound setting successful" else - echoContent red " ---> Universal subscription ${remoteDomain}:${email} does not exist" + echoContent red "================================================== ===============" fi - fi + + local singBoxSubscribe= + singBoxSubscribe=$(curl -s "${subscribeType}://${remoteUrl}/s/sing-box_profiles/${emailMD5}") + + if ! echo "${singBoxSubscribe}" | grep -q "nginx" && [[ -n "${singBoxSubscribe}" ]]; then + singBoxSubscribe=${singBoxSubscribe//tag\": \"${email}/tag\": \"${email}_${serverAlias}} + singBoxSubscribe=$(jq ". +=${singBoxSubscribe}" "/etc/v2ray-agent/subscribe_local/sing-box/${email}") + echo "${singBoxSubscribe}" | jq . >"/etc/v2ray-agent/subscribe_local/sing-box/${email}" + + echoContent green " ---> Abandon settings" + else + echoContent red "\n================================================ =================" + fi + + done < <(grep -v '^$' <"/etc/v2ray-agent/subscribe_remote/remoteSubscribeUrl") } # switch alpn switchAlpn() { - echoContent skyBlue "\nFunction 1/${totalProgress}: switch alpn" + echoContent skyBlue "-------------------------Remarks--------------------- ----------" if [[ -z ${currentAlpn} ]]; then - echoContent red " ---> Unable to read alpn, please check whether it is installed" + echoContent red "================================================== ===============" exit 0 fi - 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 "================================================== ===============" + echoContent red "\n==============================================================" + echoContent green " ---> WARP offload uninstall successful" + 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 yellow "# Does not affect the content of added remote subscriptions\n" + echoContent red "==============================================================" if [[ "${currentAlpn}" == "http/1.1" ]]; then - echoContent yellow "1.Switch alpn h2 first" + echoContent yellow "\n ---> Salt: ${subscribeSalt}" elif [[ "${currentAlpn}" == "h2" ]]; then - echoContent yellow "1.Switch alpn http/1.1 first" + echoContent yellow "--------------------------------------------------------------" else - echoContent red 'does not comply' + echoContent red " ---> IP acquisition failed, exit installation" fi - echoContent red "================================================== ===============" + echoContent red "==============================================================" read -r -p "Please select:" selectSwitchAlpnType if [[ "${selectSwitchAlpnType}" == "1" && "${currentAlpn}" == "http/1.1" ]]; then @@ -7776,7 +9483,7 @@ switchAlpn() { 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" + echoContent red "================================================== ===============" exit 0 fi reloadCore @@ -7784,361 +9491,481 @@ switchAlpn() { #Initialize realityKey initRealityKey() { - echoContent skyBlue "\n========================== Generate key ================= =========\n" - if [[ -n "${currentRealityPublicKey}" ]]; then + echoContent skyBlue "\n----------Default subscription----------\n" + if [[ -n "${currentRealityPublicKey}" && -z "${lastInstallationConfig}" ]]; 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 + elif [[ -n "${currentRealityPublicKey}" && -n "${lastInstallationConfig}" ]]; then + realityPrivateKey=${currentRealityPrivateKey} + realityPublicKey=${currentRealityPublicKey} 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}') + if [[ "${selectCoreType}" == "2" || "${coreInstallType}" == "2" ]]; then + realityX25519Key=$(/etc/v2ray-agent/sing-box/sing-box generate reality-keypair) + realityPrivateKey=$(echo "${realityX25519Key}" | head -1 | awk '{print $2}') + realityPublicKey=$(echo "${realityX25519Key}" | tail -n 1 | awk '{print $2}') + echo "publicKey:${realityPublicKey}" >/etc/v2ray-agent/sing-box/conf/config/reality_key + else + read -r -p "Enter Private Key [Enter to generate automatically]:" historyPrivateKey + if [[ -n "${historyPrivateKey}" ]]; then + realityX25519Key=$(/etc/v2ray-agent/xray/xray x25519 -i "${historyPrivateKey}") + else + realityX25519Key=$(/etc/v2ray-agent/xray/xray x25519) + fi + realityPrivateKey=$(echo "${realityX25519Key}" | grep "PrivateKey" | awk '{print $2}') + realityPublicKey=$(echo "${realityX25519Key}" | grep "Password" | awk '{print $3}') + if [[ -z "${realityPrivateKey}" ]]; then + echoContent red " ---> Wrong selection" + initRealityKey + else + echoContent green "\n privateKey:${realityPrivateKey}" + echoContent green "\n publicKey:${realityPublicKey}" + fi + fi + fi +} +initRealityMldsa65() { + echoContent skyBlue "\n----------clashMeta subscription----------\n" + if /etc/v2ray-agent/xray/xray tls ping "${realityServerName}:${realityDomainPort}" 2>/dev/null | grep -q "X25519MLKEM768"; then + length=$(/etc/v2ray-agent/xray/xray tls ping "${realityServerName}:${realityDomainPort}" | grep "Certificate chain's total length:" | awk '{print $5}' | head -1) + + if [ "$length" -gt 3500 ]; then + if [[ -n "${currentRealityMldsa65Seed}" && -z "${lastInstallationConfig}" ]]; then + read -r -p "Previous Seed/Verify values found. Use them? [y/n]:" historyMldsa65Status + if [[ "${historyMldsa65Status}" == "y" ]]; then + realityMldsa65Seed=${currentRealityMldsa65Seed} + realityMldsa65Verify=${currentRealityMldsa65Verify} + fi + elif [[ -n "${currentRealityMldsa65Seed}" && -n "${lastInstallationConfig}" ]]; then + realityMldsa65Seed=${currentRealityMldsa65Seed} + realityMldsa65Verify=${currentRealityMldsa65Verify} + fi + if [[ -z "${realityMldsa65Seed}" ]]; then + # if [[ "${selectCoreType}" == "2" || "${coreInstallType}" == "2" ]]; then + # realityX25519Key=$(/etc/v2ray-agent/sing-box/sing-box generate reality-keypair) + # realityPrivateKey=$(echo "${realityX25519Key}" | head -1 | awk '{print $2}') + # realityPublicKey=$(echo "${realityX25519Key}" | tail -n 1 | awk '{print $2}') + # echo "publicKey:${realityPublicKey}" >/etc/v2ray-agent/sing-box/conf/config/reality_key + # else + realityMldsa65=$(/etc/v2ray-agent/xray/xray mldsa65) + realityMldsa65Seed=$(echo "${realityMldsa65}" | head -1 | awk '{print $2}') + realityMldsa65Verify=$(echo "${realityMldsa65}" | tail -n 1 | awk '{print $2}') + # fi + fi + # echoContent green "\n Seed:${realityMldsa65Seed}" + # echoContent green "\n Verify:${realityMldsa65Verify}" + else + echoContent green " ---> Added successfully" + fi + else + echoContent green " ---> WARP global outbound setting successful" 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" + echoContent red "\n================================================ =================" read -r -p "Continue? [y/n]" setRealityDestStatus if [[ "${setRealityDestStatus}" != 'y' ]]; then exit 0 fi - echoContent yellow "\n --->Ignore the risks and continue using" + echoContent yellow "url:https://${currentDomain}/s/default/${emailMd5}\n" 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\" + local realityDestDomainList= + if [[ "${coreInstallType}" == "1" || "${selectCoreType}" == "1" ]]; then + realityDestDomainList="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,academy.nvidia.com,dl.google.com,www.google-analytics.com,www.caltech.edu,www.calstatela.edu,www.suny.edu,www.suffolk.edu,www.python.org,vuejs-jp.org,vuejs.org,zh-hk.vuejs.org,react.dev,www.java.com,www.oracle.com,www.mysql.com,www.mongodb.com,redis.io,cname.vercel-dns.com,vercel-dns.com,www.swift.com,academy.nvidia.com,www.swift.com,www.cisco.com,www.asus.com,www.samsung.com,www.amd.com,www.umcg.nl,www.fom-international.com,www.u-can.co.jp,github.io" + elif [[ "${coreInstallType}" == "2" || "${selectCoreType}" == "2" ]]; then + realityDestDomainList="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,www.lovelive-anime.jp,academy.nvidia.com,dl.google.com,www.google-analytics.com,www.python.org,vuejs-jp.org,vuejs.org,zh-hk.vuejs.org,react.dev,www.oracle.com,www.mysql.com,www.mongodb.com,cname.vercel-dns.com,vercel-dns.com,www.swift.com,academy.nvidia.com,www.swift.com,www.cisco.com,www.asus.com,www.samsung.com,www.amd.com,www.fom-international.com,github.io" + fi + if [[ -n "${realityServerName}" && -z "${lastInstallationConfig}" ]]; then + if echo ${realityDestDomainList} | grep -q "${realityServerName}"; then + read -r -p "Previous Reality server name found. Use it? [y/n]:" realityServerNameStatus + if [[ "${realityServerNameStatus}" != "y" ]]; then + realityServerName= + realityDomainPort= + fi else - realityServerNames=\"${realityServerNames//,/\",\"}\" + realityServerName= + realityDomainPort= + fi + elif [[ -n "${realityServerName}" && -z "${lastInstallationConfig}" ]]; then + realityServerName= + realityDomainPort= + fi + + if [[ -z "${realityServerName}" ]]; then + if [[ -n "${domain}" ]]; then + echo + read -r -p "Use ${domain} as the Reality target domain? [y/n]:" realityServerNameCurrentDomainStatus + if [[ "${realityServerNameCurrentDomainStatus}" == "y" ]]; then + realityServerName="${domain}" + if [[ "${selectCoreType}" == "1" ]]; then + if [[ -z "${subscribePort}" ]]; then + echo + installSubscribe + readNginxSubscribe + realityDomainPort="${subscribePort}" + else + realityDomainPort="${subscribePort}" + fi + fi + if [[ "${selectCoreType}" == "2" ]]; then + if [[ -z "${subscribePort}" ]]; then + echo + installSubscribe + readNginxSubscribe + realityDomainPort="${subscribePort}" + else + realityDomainPort="${subscribePort}" + fi + fi + fi + fi + if [[ -z "${realityServerName}" ]]; then + realityDomainPort=443 + echoContent skyBlue "------------------------------------------------- ---------------" + echoContent yellow "Online QR code: https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentDomain}/s/default/${emailMd5}\n " + echoContent green " ---> Abandon settings" + echoContent yellow "url:https://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n" + read -r -p "Enter target domain [Enter for random; default port 443]:" realityServerName + if [[ -z "${realityServerName}" ]]; then + count=$(echo ${realityDestDomainList} | awk -F',' '{print NF}') + randomNum=$(randomNum 1 "${count}") + + realityServerName=$(echo "${realityDestDomainList}" | awk -F ',' -v randomNum="$randomNum" '{print $randomNum}') + fi + if echo "${realityServerName}" | grep -q ":"; then + realityDomainPort=$(echo "${realityServerName}" | awk -F "[:]" '{print $2}') + realityServerName=$(echo "${realityServerName}" | awk -F "[:]" '{print $1}') + fi fi fi - echoContent yellow "\n ---> Available client domain names: ${realityServerNames}\n" + echoContent yellow "Online QR code: https://api.qrserver.com/v1/create-qr-code/?size=400x400&data=https://${currentDomain}/s/clashMetaProfiles/${emailMd5}\n " } -#Initialize the reality port -initRealityPort() { - if [[ -n "${currentRealityPort}" ]]; then +initXrayRealityPort() { + if [[ -n "${xrayVLESSRealityPort}" && -z "${lastInstallationConfig}" ]]; 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} + realityPort=${xrayVLESSRealityPort} fi + elif [[ -n "${xrayVLESSRealityPort}" && -n "${lastInstallationConfig}" ]]; then + realityPort=${xrayVLESSRealityPort} 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]" + # if [[ -n "${port}" ]]; then + # if [[ "${realityPortTLSVisionStatus}" == "y" ]]; then + # realityPort=${port} + # fi + # fi + # if [[ -z "${realityPort}" ]]; then + 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]" + read -r -p "port:" realityPort - if [[ -z "${realityPort}" ]]; then - realityPort=$((RANDOM % 20001 + 10000)) - fi + if [[ -z "${realityPort}" ]]; then + realityPort=$((RANDOM % 20001 + 10000)) fi - if [[ -n "${realityPort}" && "${currentRealityPort}" == "${realityPort}" ]]; then + # fi + if [[ -n "${realityPort}" && "${xrayVLESSRealityPort}" == "${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 + initXrayRealityPort else allowPort "${realityPort}" - echoContent yellow "\n ---> Port: ${realityPort}" + echoContent yellow "2.When h2 is the first, gRPC is available, and some trojan clients are available [the client supports manual selection of alpn]" 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() { +initXrayXHTTPort() { + if [[ -n "${xrayVLESSRealityXHTTPort}" && -z "${lastInstallationConfig}" ]]; then + read -r -p "Previous installation port found. Use it? [y/n]:" historyXHTTPortStatus + if [[ "${historyXHTTPortStatus}" == "y" ]]; then + xHTTPort=${xrayVLESSRealityXHTTPort} + fi + elif [[ -n "${xrayVLESSRealityXHTTPort}" && -n "${lastInstallationConfig}" ]]; then + xHTTPort=${xrayVLESSRealityXHTTPort} + fi - 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 + if [[ -z "${xHTTPort}" ]]; then + + 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" + read -r -p "Port:" xHTTPort + if [[ -z "${xHTTPort}" ]]; then + xHTTPort=$((RANDOM % 20001 + 10000)) + fi + if [[ -n "${xHTTPort}" && "${xrayVLESSRealityXHTTPort}" == "${xHTTPort}" ]]; then + handleXray stop + else + checkPort "${xHTTPort}" + fi + fi + if [[ -z "${xHTTPort}" ]]; then + initXrayXHTTPort + else + allowPort "${xHTTPort}" + allowPort "${xHTTPort}" "udp" + echoContent yellow "1.Switch alpn h2 first" + fi } + #realitymanagement manageReality() { + readInstallProtocolType + readConfigHostPathUUID + readCustomPort + readSingBoxConfig - 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" + if ! echo "${currentInstallProtocolType}" | grep -q -E "7,|8," || [[ -z "${coreInstallType}" ]]; then + echoContent red "\n================================================ ============ =====" + exit 0 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 + if [[ "${coreInstallType}" == "1" ]]; then + selectCustomInstallType=",7," + initXrayConfig custom 1 true + elif [[ "${coreInstallType}" == "2" ]]; then + if echo "${currentInstallProtocolType}" | grep -q ",7,"; then + selectCustomInstallType=",7," + fi + if echo "${currentInstallProtocolType}" | grep -q ",8,"; then + selectCustomInstallType="${selectCustomInstallType},8," + fi + initSingBoxConfig custom 1 true fi + + reloadCore + subscribe false } -# hysteriaadmin -manageHysteria() { - echoContent skyBlue "\nProgress 1/1: Hysteria Management" +installRealityScanner() { + if [[ ! -f "/etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64" ]]; then + version=$(curl -s https://api.github.com/repos/XTLS/RealiTLScanner/releases?per_page=1 | jq -r '.[]|.tag_name') + wget -c -q -P /etc/v2ray-agent/xray/reality_scan/ "https://github.com/XTLS/RealiTLScanner/releases/download/${version}/RealiTLScanner-linux-64" + chmod 655 /etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64 + fi +} +# reality scanner +realityScanner() { + echoContent skyBlue "\nFunction 1/${totalProgress}: switch alpn" + echoContent red "\n==============================================================" + echoContent yellow "1.Switch alpn http/1.1 first" + echoContent yellow "\n --->Ignore the risks and continue using" 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" + echoContent yellow "\n ---> Fallback domain name: ${realityDestDomain}" + echoContent yellow "#Notes" + echoContent red "==============================================================" + read -r -p "Select:" realityScannerStatus + local type= + if [[ "${realityScannerStatus}" == "1" ]]; then + type=4 + elif [[ "${realityScannerStatus}" == "2" ]]; then + type=6 fi + read -r -p "Some providers disallow scanning (for example Bandwagon). Continue at your own risk? [y/n]:" scanStatus + + if [[ "${scanStatus}" != "y" ]]; then + exit 0 + fi + + publicIP=$(getPublicIP "${type}") + echoContent yellow "IP:${publicIP}" + if [[ -z "${publicIP}" ]]; then + echoContent red "\n================================================ =================" + exit 0 + fi + + read -r -p "Is the IP address correct? [y/n]:" ipStatus + if [[ "${ipStatus}" == "y" ]]; then + echoContent yellow "Input example: addons.mozilla.org\n" + /etc/v2ray-agent/xray/reality_scan/RealiTLScanner-linux-64 -addr "${publicIP}" | tee /etc/v2ray-agent/xray/reality_scan/result.log + else 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 +} +# hysteriaadmin +manageHysteria() { + echoContent skyBlue "\n========================== Generate key ================= =========\n" + echoContent red "\n==============================================================" + local hysteria2Status= + if [[ -n "${singBoxConfigPath}" ]] && [[ -f "/etc/v2ray-agent/sing-box/conf/config/06_hysteria2_inbounds.json" ]]; then + echoContent yellow "\n ---> Available client domain names: ${realityServerNames}\n" + echoContent yellow "Please enter the port [Enter random 10000-30000]" + echoContent yellow "\n ---> Port: ${realityPort}" + echoContent yellow "1.Reinstall" + hysteria2Status=true + else + echoContent yellow "2.Uninstall" + echoContent yellow "3.Change configuration" + fi + + echoContent red "==============================================================" + read -r -p "Select:" installHysteria2Status + if [[ "${installHysteria2Status}" == "1" ]]; then + singBoxHysteria2Install + elif [[ "${installHysteria2Status}" == "2" && "${hysteria2Status}" == "true" ]]; then + unInstallSingBox hysteria2 + elif [[ "${installHysteria2Status}" == "3" && "${hysteria2Status}" == "true" ]]; then + portHoppingMenu hysteria2 fi } #tuicadmin manageTuic() { - echoContent skyBlue "\nProgress 1/1: Tuic Management" - echoContent red "\n================================================ =================" + echoContent skyBlue "\n====== Generate a domain name with fallback configuration , for example : [addons.mozilla.org:443] ======\n" + echoContent red "\n==============================================================" local tuicStatus= - if [[ -n "${tuicConfigPath}" ]]; then + if [[ -n "${singBoxConfigPath}" ]] && [[ -f "/etc/v2ray-agent/sing-box/conf/config/09_tuic_inbounds.json" ]]; then + echoContent yellow "1.Installation" + echoContent yellow "1.Reinstall" + echoContent yellow "2.Uninstall" + echoContent yellow "3.Port jump management" + tuicStatus=true + else + echoContent yellow "4.core management" + echoContent yellow "5.View log" + fi + + echoContent red "==============================================================" + read -r -p "Please select:" installTuicStatus + if [[ "${installTuicStatus}" == "1" ]]; then + singBoxTuicInstall + elif [[ "${installTuicStatus}" == "2" && "${tuicStatus}" == "true" ]]; then + unInstallSingBox tuic + elif [[ "${installTuicStatus}" == "3" && "${tuicStatus}" == "true" ]]; then + portHoppingMenu tuic + fi +} +singBoxLog() { + cat </etc/v2ray-agent/sing-box/conf/config/log.json +{ + "log": { + "disabled": $1, + "level": "debug", + "output": "/etc/v2ray-agent/sing-box/conf/box.log", + "timestamp": true + } +} +EOF + + handleSingBox stop + handleSingBox start +} + +singBoxVersionManageMenu() { + echoContent skyBlue "\n================ Configure serverNames available to the client ================\n" + if [[ -z "${singBoxConfigPath}" ]]; then + echoContent red " ---> Domain name cannot be empty" + menu + exit 0 + fi + echoContent red "\n==============================================================" + echoContent yellow "1.Installation" echoContent yellow "1.Reinstall" echoContent yellow "2.Uninstall" echoContent yellow "3.core management" + echoContent yellow "==============================================================" + local logStatus= + if [[ -n "${singBoxConfigPath}" && -f "${singBoxConfigPath}log.json" && "$(jq -r .log.disabled "${singBoxConfigPath}log.json")" == "false" ]]; then echoContent yellow "4.View log" - tuicStatus=true + logStatus=true else echoContent yellow "1.Installation" + logStatus=false 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 "================================================== ===============" + 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 + read -r -p "Select:" selectSingBoxType + if [[ ! -f "${singBoxConfigPath}../box.log" ]]; then + touch "${singBoxConfigPath}../box.log" >/dev/null 2>&1 + fi + if [[ "${selectSingBoxType}" == "1" ]]; then + installSingBox 1 + handleSingBox stop + handleSingBox start + elif [[ "${selectSingBoxType}" == "2" ]]; then + handleSingBox stop + elif [[ "${selectSingBoxType}" == "3" ]]; then + handleSingBox start + elif [[ "${selectSingBoxType}" == "4" ]]; then + handleSingBox stop + handleSingBox start + elif [[ "${selectSingBoxType}" == "5" ]]; then + singBoxLog ${logStatus} + if [[ "${logStatus}" == "false" ]]; then + tail -f "${singBoxConfigPath}../box.log" + fi + elif [[ "${selectSingBoxType}" == "6" ]]; then + tail -f "${singBoxConfigPath}../box.log" 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: v3.5.13" - echoContent green "Github: https://github.com/mack-a/v2ray-agent" - echoContent green "Description: 8-in-1 coexistence script\c" + echoContent red "\n==============================================================" + echoContent green " ---> WARP offload uninstall successful" + echoContent green " ---> Added shunt successfully" + echoContent green "Github:https://github.com/mack-a/v2ray-agent" + echoContent green " ---> Add any door to divert successfully" 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 "================================================== ===============" + echoContent red " ---> Port cannot be empty" + echoContent red " " + echoContent yellow "2.Close Hysteria" + echoContent green "https://www.v2ray-agent.com/archives/1679975663984" + echoContent yellow "3.Open Hysteria" + echoContent green "https://www.v2ray-agent.com/archives/racknerdtao-can-zheng-li-nian-fu-10mei-yuan" + echoContent yellow "4.Restart Hysteria" + echoContent green "https://www.v2ray-agent.com/archives/186cee7b-9459-4e57-b9b2-b07a4f36931c" + echoContent yellow "1.Upgrade Tuic" + echoContent red " " + echoContent red "==============================================================" if [[ -n "${coreInstallType}" ]]; then - echoContent yellow "1.Reinstall" + echoContent yellow "2.Close Tuic" else + echoContent yellow "3.Open Tuic" + fi + + echoContent yellow "4.Restart Tuic" + echoContent yellow "1.Reinstall" 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 skyBlue "\nProgress$1/${totalProgress}: Initializing Xray-core reality configuration" + echoContent yellow "3.Switch Trojan[XTLS]" 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 skyBlue "\nProgress 1/1: reality management" echoContent yellow "11.Diversion tool" echoContent yellow "12.Add new port" echoContent yellow "13.BT download management" + echoContent skyBlue "\nProgress 1/1: Hysteria 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 "================================================== ===============" + echoContent red "==============================================================" mkdirTools aliasInstall read -r -p "Please select:" selectInstallType @@ -8150,7 +9977,7 @@ menu() { selectCoreInstall ;; 3) - initXrayFrontingConfig 1 + selectCoreInstall ;; 4) manageHysteria @@ -8171,7 +9998,7 @@ menu() { renewalTLS 1 ;; 10) - updateV2RayCDN 1 + manageCDN 1 ;; 11) routingToolsMenu 1 @@ -8197,9 +10024,6 @@ menu() { 18) bbrInstall ;; - 19) - checkLog 1 - ;; 20) unInstall 1 ;;