| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867 |
- #!/usr/bin/env bash
- PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin:~/bin
- export PATH
- #=================================================
- # System Required: CentOS/Debian/Ubuntu
- # Description: Shadowsocks Rust 管理脚本
- # Author: 翠花
- # WebSite: https://about.nange.cn
- #=================================================
- # 当前脚本版本号
- sh_ver="1.5.3"
- # Shadowsocks Rust 相关路径
- SS_Folder="/etc/ss-rust"
- SS_File="/usr/local/bin/ss-rust"
- SS_Conf="/etc/ss-rust/config.json"
- SS_Now_ver_File="/etc/ss-rust/ver.txt"
- # BBR 配置文件
- BBR_Local="/etc/sysctl.d/local.conf"
- # Shadow TLS 相关路径
- STLS_Folder="/etc/shadowtls"
- STLS_File="/usr/local/bin/shadow-tls"
- STLS_Conf="/etc/shadowtls/config.json"
- STLS_Now_ver_File="/etc/shadowtls/ver.txt"
- Green_font_prefix="\033[32m" && Red_font_prefix="\033[31m" && Green_background_prefix="\033[42;37m" && Red_background_prefix="\033[41;37m" && Font_color_suffix="\033[0m" && Yellow_font_prefix="\033[0;33m"
- Info="${Green_font_prefix}[信息]${Font_color_suffix}"
- Error="${Red_font_prefix}[错误]${Font_color_suffix}"
- Tip="${Yellow_font_prefix}[注意]${Font_color_suffix}"
- check_root(){
- if [[ $EUID != 0 ]]; then
- echo -e "${Error} 当前非ROOT账号(或没有ROOT权限),无法继续操作,请更换ROOT账号或使用 ${Green_background_prefix}sudo su${Font_color_suffix} 命令获取临时ROOT权限(执行后可能会提示输入当前账号的密码)。"
- exit 1
- fi
- }
- check_sys(){
- if [[ -f /etc/redhat-release ]]; then
- release="centos"
- elif cat /etc/issue | grep -q -E -i "debian"; then
- release="debian"
- elif cat /etc/issue | grep -q -E -i "ubuntu"; then
- release="ubuntu"
- elif cat /etc/issue | grep -q -E -i "centos|red hat|redhat"; then
- release="centos"
- elif cat /proc/version | grep -q -E -i "debian"; then
- release="debian"
- elif cat /proc/version | grep -q -E -i "ubuntu"; then
- release="ubuntu"
- elif cat /proc/version | grep -q -E -i "centos|red hat|redhat"; then
- release="centos"
- fi
- }
- sys_arch() {
- uname=$(uname -m)
- if [[ "$uname" == "i686" ]] || [[ "$uname" == "i386" ]]; then
- arch="i686"
- elif [[ "$uname" == *"armv7"* ]] || [[ "$uname" == "armv6l" ]]; then
- arch="arm"
- elif [[ "$uname" == *"armv8"* ]] || [[ "$uname" == "aarch64" ]]; then
- arch="aarch64"
- else
- arch="x86_64"
- fi
- }
- #开启系统 TCP Fast Open
- enable_systfo() {
- kernel=$(uname -r | awk -F . '{print $1}')
- if [ "$kernel" -ge 3 ]; then
- echo 3 >/proc/sys/net/ipv4/tcp_fastopen
- [[ ! -e $BBR_Local ]] && echo "fs.file-max = 51200
- net.core.rmem_max = 67108864
- net.core.wmem_max = 67108864
- net.core.rmem_default = 65536
- net.core.wmem_default = 65536
- net.core.netdev_max_backlog = 4096
- net.core.somaxconn = 4096
- net.ipv4.tcp_syncookies = 1
- net.ipv4.tcp_tw_reuse = 1
- net.ipv4.tcp_tw_recycle = 0
- net.ipv4.tcp_fin_timeout = 30
- net.ipv4.tcp_keepalive_time = 1200
- net.ipv4.ip_local_port_range = 10000 65000
- net.ipv4.tcp_max_syn_backlog = 4096
- net.ipv4.tcp_max_tw_buckets = 5000
- net.ipv4.tcp_fastopen = 3
- net.ipv4.tcp_rmem = 4096 87380 67108864
- net.ipv4.tcp_wmem = 4096 65536 67108864
- net.ipv4.tcp_mtu_probing = 1
- net.ipv4.tcp_ecn=1
- net.core.default_qdisc=fq
- net.ipv4.tcp_congestion_control = bbr" >>/etc/sysctl.d/local.conf && sysctl --system >/dev/null 2>&1
- else
- echo -e "$Error系统内核版本过低,无法支持 TCP Fast Open !"
- fi
- }
- check_installed_status(){
- [[ ! -e ${SS_File} ]] && echo -e "${Error} Shadowsocks Rust 没有安装,请检查!" && exit 1
- }
- check_status(){
- status=`systemctl status ss-rust | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1`
- }
- check_new_ver(){
- new_ver=$(wget -qO- https://api.github.com/repos/shadowsocks/shadowsocks-rust/releases| jq -r '[.[] | select(.prerelease == false) | select(.draft == false) | .tag_name] | .[0]')
- [[ -z ${new_ver} ]] && echo -e "${Error} Shadowsocks Rust 最新版本获取失败!" && exit 1
- echo -e "${Info} 检测到 Shadowsocks Rust 最新版本为 [ ${new_ver} ]"
- }
- check_ver_comparison(){
- now_ver=$(cat ${SS_Now_ver_File})
- if [[ "${now_ver}" != "${new_ver}" ]]; then
- echo -e "${Info} 发现 Shadowsocks Rust 已有新版本 [ ${new_ver} ],旧版本 [ ${now_ver} ]"
- read -e -p "是否更新 ? [Y/n]:" yn
- [[ -z "${yn}" ]] && yn="y"
- if [[ $yn == [Yy] ]]; then
- check_status
- # [[ "$status" == "running" ]] && systemctl stop ss-rust
- \cp "${SS_Conf}" "/tmp/config.json"
- # rm -rf ${SS_Folder}
- download
- mv -f "/tmp/config.json" "${SS_Conf}"
- restart
- fi
- else
- echo -e "${Info} 当前 Shadowsocks Rust 已是最新版本 [ ${new_ver} ] !" && exit 1
- fi
- }
- # 官方源
- stable_download() {
- echo -e "${Info} 默认开始下载官方源 Shadowsocks Rust ……"
- wget --no-check-certificate -N "https://github.com/shadowsocks/shadowsocks-rust/releases/download/${new_ver}/shadowsocks-${new_ver}.${arch}-unknown-linux-gnu.tar.xz"
- if [[ ! -e "shadowsocks-${new_ver}.${arch}-unknown-linux-gnu.tar.xz" ]]; then
- echo -e "${Error} Shadowsocks Rust 官方源下载失败!"
- return 1 && exit 1
- else
- tar -xvf "shadowsocks-${new_ver}.${arch}-unknown-linux-gnu.tar.xz"
- fi
- if [[ ! -e "ssserver" ]]; then
- echo -e "${Error} Shadowsocks Rust 解压失败!"
- echo -e "${Error} Shadowsocks Rust 安装失败 !"
- return 1 && exit 1
- else
- rm -rf "shadowsocks-${new_ver}.${arch}-unknown-linux-gnu.tar.xz"
- chmod +x ssserver
- mv -f ssserver "${SS_File}"
- rm sslocal ssmanager ssservice ssurl
- echo "${new_ver}" > ${SS_Now_ver_File}
- echo -e "${Info} Shadowsocks Rust 主程序下载安装完毕!"
- return 0
- fi
- }
- # 备用源
- backup_download() {
- echo -e "${Info} 试图请求 备份源(旧版本) Shadowsocks Rust ……"
- wget --no-check-certificate -N "https://raw.githubusercontent.com/xOS/Others/master/shadowsocks-rust/v1.14.1/shadowsocks-v1.14.1.${arch}-unknown-linux-gnu.tar.xz"
- if [[ ! -e "shadowsocks-v1.14.1.${arch}-unknown-linux-gnu.tar.xz" ]]; then
- echo -e "${Error} Shadowsocks Rust 备份源(旧版本) 下载失败!"
- return 1 && exit 1
- else
- tar -xvf "shadowsocks-v1.14.1.${arch}-unknown-linux-gnu.tar.xz"
- fi
- if [[ ! -e "ssserver" ]]; then
- echo -e "${Error} Shadowsocks Rust 备份源(旧版本) 解压失败 !"
- echo -e "${Error} Shadowsocks Rust 备份源(旧版本) 安装失败 !"
- return 1 && exit 1
- else
- rm -rf "shadowsocks-v1.14.1.${arch}-unknown-linux-gnu.tar.xz"
- chmod +x ssserver
- mv -f ssserver "${SS_File}"
- rm sslocal ssmanager ssservice ssurl
- echo "v1.14.1" > ${SS_Now_ver_File}
- echo -e "${Info} Shadowsocks Rust 备份源(旧版本) 主程序下载安装完毕!"
- return 0
- fi
- }
- download() {
- if [[ ! -e "${SS_Folder}" ]]; then
- mkdir "${SS_Folder}"
- # else
- # [[ -e "${SS_File}" ]] && rm -rf "${SS_File}"
- fi
- stable_download
- if [[ $? != 0 ]]; then
- backup_download
- fi
- }
- # Shadow TLS 官方源下载
- stable_download_stls() {
- echo -e "${Info} 默认开始下载官方源 Shadow TLS ……"
- wget --no-check-certificate -N "https://github.com/ihciah/shadow-tls/releases/download/${stls_new_ver}/shadow-tls-${arch}-unknown-linux-musl"
- if [[ ! -e "shadow-tls-${arch}-unknown-linux-musl" ]]; then
- echo -e "${Error} Shadow TLS 官方源下载失败!"
- return 1 && exit 1
- else
- chmod +x "shadow-tls-${arch}-unknown-linux-musl"
- mv -f "shadow-tls-${arch}-unknown-linux-musl" "${STLS_File}"
- echo "${stls_new_ver}" > ${STLS_Now_ver_File}
- echo -e "${Info} Shadow TLS 主程序下载安装完毕!"
- return 0
- fi
- }
- download_stls() {
- if [[ ! -e "${STLS_Folder}" ]]; then
- mkdir "${STLS_Folder}"
- fi
- stable_download_stls
- }
- # Shadow TLS 配置相关函数
- set_stls_port(){
- while true
- do
- echo -e "${Tip} Shadow TLS 端口需与防火墙端口一致!"
- echo -e "请输入 Shadow TLS 端口 [1-65535]"
- read -e -p "(默认:8443):" stls_port
- [[ -z "${stls_port}" ]] && stls_port="8443"
- echo $((${stls_port}+0)) &>/dev/null
- if [[ $? -eq 0 ]]; then
- if [[ ${stls_port} -ge 1 ]] && [[ ${stls_port} -le 65535 ]]; then
- echo && echo "========================================"
- echo -e "Shadow TLS 端口:${Red_background_prefix} ${stls_port} ${Font_color_suffix}"
- echo "========================================" && echo
- break
- else
- echo "输入错误, 请输入正确的端口。"
- fi
- else
- echo "输入错误, 请输入正确的端口。"
- fi
- done
- }
- set_stls_password(){
- echo "请输入 Shadow TLS 密码 [0-9][a-z][A-Z]"
- read -e -p "(默认:随机生成):" stls_password
- [[ -z "${stls_password}" ]] && stls_password=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | head -c 16)
- echo && echo "========================================"
- echo -e "Shadow TLS 密码:${Red_background_prefix} ${stls_password} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_stls_sni(){
- echo "请输入 Shadow TLS SNI 域名"
- read -e -p "(默认:cloudflare.com):" stls_sni
- [[ -z "${stls_sni}" ]] && stls_sni="cloudflare.com"
- echo && echo "========================================"
- echo -e "Shadow TLS SNI:${Red_background_prefix} ${stls_sni} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_stls_fastopen(){
- echo -e "是否开启 Shadow TLS TCP Fast Open ?
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} 开启 ${Green_font_prefix} 2.${Font_color_suffix} 关闭
- ========================================"
- read -e -p "(默认:1.开启):" stls_fastopen_choice
- [[ -z "${stls_fastopen_choice}" ]] && stls_fastopen_choice="1"
- if [[ ${stls_fastopen_choice} == "1" ]]; then
- stls_fastopen="true"
- else
- stls_fastopen="false"
- fi
- echo && echo "========================================"
- echo -e "Shadow TLS FastOpen:${Red_background_prefix} ${stls_fastopen} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_stls_strict(){
- echo -e "是否开启 Shadow TLS Strict 模式 ?
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} 开启 ${Green_font_prefix} 2.${Font_color_suffix} 关闭
- ========================================"
- read -e -p "(默认:1.开启):" stls_strict_choice
- [[ -z "${stls_strict_choice}" ]] && stls_strict_choice="1"
- if [[ ${stls_strict_choice} == "1" ]]; then
- stls_strict="true"
- else
- stls_strict="false"
- fi
- echo && echo "========================================"
- echo -e "Shadow TLS Strict:${Red_background_prefix} ${stls_strict} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_stls_tls_wildcard_sni(){
- echo -e "请选择 Shadow TLS Wildcard SNI 模式:
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} authed (默认)
- ${Green_font_prefix} 2.${Font_color_suffix} off
- ${Green_font_prefix} 3.${Font_color_suffix} all
- ========================================"
- read -e -p "(默认:1.authed):" stls_tls_wildcard_sni_choice
- [[ -z "${stls_tls_wildcard_sni_choice}" ]] && stls_tls_wildcard_sni_choice="1"
- case "${stls_tls_wildcard_sni_choice}" in
- 1) stls_tls_wildcard_sni="authed" ;;
- 2) stls_tls_wildcard_sni="off" ;;
- 3) stls_tls_wildcard_sni="all" ;;
- *) stls_tls_wildcard_sni="authed" ;;
- esac
- echo && echo "========================================"
- echo -e "TLS Wildcard SNI:${Red_background_prefix} ${stls_tls_wildcard_sni} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_stls_fallback(){
- echo "请输入 Shadow TLS 回退域名"
- read -e -p "(默认:cloud.tencent.com:443):" stls_fallback
- [[ -z "${stls_fallback}" ]] && stls_fallback="cloud.tencent.com:443"
- echo && echo "========================================"
- echo -e "Shadow TLS 回退域名:${Red_background_prefix} ${stls_fallback} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- service(){
- echo "
- [Unit]
- Description= Shadowsocks Rust Service
- After=network-online.target
- Wants=network-online.target systemd-networkd-wait-online.service
- [Service]
- LimitNOFILE=32767
- Type=simple
- User=root
- Restart=on-failure
- RestartSec=5s
- DynamicUser=true
- ExecStartPre=/bin/sh -c 'ulimit -n 51200'
- ExecStart=${SS_File} -c ${SS_Conf}
- [Install]
- WantedBy=multi-user.target" > /etc/systemd/system/ss-rust.service
- systemctl enable --now ss-rust
- echo -e "${Info} Shadowsocks Rust 服务配置完成!"
- }
- service_stls(){
- cat > /etc/systemd/system/shadowtls.service<<-EOF
- [Unit]
- Description=Shadow TLS Service
- After=network-online.target
- Wants=network-online.target systemd-networkd-wait-online.service
- [Service]
- LimitNOFILE=32767
- Type=simple
- User=root
- Restart=on-failure
- RestartSec=5s
- Environment=MONOIO_FORCE_LEGACY_DRIVER=1
- ExecStartPre=/bin/sh -c 'ulimit -n 51200'
- ExecStart=${STLS_File} config --config ${STLS_Conf}
- [Install]
- WantedBy=multi-user.target
- EOF
- systemctl enable --now shadowtls
- echo -e "${Info} Shadow TLS 服务配置完成!"
- }
- installation_dependency(){
- if [[ ${release} == "centos" ]]; then
- yum update
- yum install jq gzip wget curl unzip xz openssl -y
- else
- apt-get update
- apt-get install jq gzip wget curl unzip xz-utils openssl -y
- fi
- \cp -f /usr/share/zoneinfo/Asia/Shanghai /etc/localtime
- }
- write_config(){
- cat > ${SS_Conf}<<-EOF
- {
- "server": "::",
- "server_port": ${port},
- "password": "${password}",
- "method": "${cipher}",
- "fast_open": ${tfo},
- "mode": "tcp_and_udp",
- "user":"nobody",
- "timeout":300,
- "nameserver":"1.1.1.1"
- }
- EOF
- }
- write_stls_config(){
- # 设置默认值
- [[ -z "${stls_fastopen}" ]] && stls_fastopen="true"
- [[ -z "${stls_strict}" ]] && stls_strict="true"
- [[ -z "${stls_tls_wildcard_sni}" ]] && stls_tls_wildcard_sni="authed"
- [[ -z "${stls_fallback}" ]] && stls_fallback="cloud.tencent.com:443"
-
- # 构建 dispatch 配置
- if [[ -z "${stls_dispatch}" ]]; then
- # 没有现有配置,使用默认配置
- # SNI 域名对应的目标地址也使用相同的域名:443
- stls_dispatch_config="\"${stls_sni}\": \"${stls_sni}:443\",
- \"captive.apple.com\": \"captive.apple.com:443\""
- else
- # 有现有配置,需要智能更新 SNI
- if [[ ! -z "${stls_sni}" && -e ${STLS_Conf} ]]; then
- # 查找需要更新的 SNI(排除 captive.apple.com)
- old_sni=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | keys[] | select(. != "captive.apple.com")' 2>/dev/null | head -1)
- if [[ ! -z "${old_sni}" && "${old_sni}" != "null" && "${old_sni}" != "${stls_sni}" ]]; then
- # 需要替换旧的 SNI 为新的 SNI,同时更新键和值
- echo -e "${Info} 更新主要 SNI 从 ${old_sni} 到 ${stls_sni}"
-
- # 使用 jq 来精确替换键和值
- stls_dispatch_config=$(cat ${STLS_Conf} | jq -r --arg old_sni "${old_sni}" --arg new_sni "${stls_sni}" '
- .server.tls_addr.dispatch |
- to_entries |
- map(if .key == $old_sni then (.key = $new_sni | .value = ($new_sni + ":443")) else . end) |
- map("\"\(.key)\": \"\(.value)\"") |
- join(",\n ")
- ' 2>/dev/null)
-
- # 如果 jq 处理失败,回退到字符串替换
- if [[ -z "${stls_dispatch_config}" || "${stls_dispatch_config}" == "null" ]]; then
- echo -e "${Info} jq 处理失败,使用字符串替换"
- # 先替换键,再替换对应的值
- stls_dispatch_config=$(echo "${stls_dispatch}" | sed "s/\"${old_sni}\": \"[^\"]*\"/\"${stls_sni}\": \"${stls_sni}:443\"/g")
- fi
- else
- # 如果没有找到需要更新的 SNI,或者 SNI 已经是正确的,直接使用现有配置
- stls_dispatch_config="${stls_dispatch}"
- fi
- else
- stls_dispatch_config="${stls_dispatch}"
- fi
- fi
-
- # 调试信息(可选,用于排查问题)
- # echo -e "${Info} 调试信息:"
- # echo -e " stls_sni: ${stls_sni}"
- # echo -e " stls_dispatch_config: ${stls_dispatch_config}"
-
- cat > ${STLS_Conf}<<-EOF
- {
- "disable_nodelay": false,
- "fastopen": ${stls_fastopen},
- "v3": true,
- "strict": ${stls_strict},
- "server": {
- "listen": "0.0.0.0:${stls_port}",
- "server_addr": "127.0.0.1:${port}",
- "tls_addr": {
- "wildcard_sni": "${stls_tls_wildcard_sni}",
- "dispatch": {
- ${stls_dispatch_config}
- },
- "fallback": "${stls_fallback}"
- },
- "password": "${stls_password}",
- "wildcard_sni": "authed"
- }
- }
- EOF
-
- # 验证配置文件是否正确生成
- if [[ -e ${STLS_Conf} ]]; then
- # 检查配置文件是否为有效的 JSON
- if ! jq . ${STLS_Conf} >/dev/null 2>&1; then
- echo -e "${Error} Shadow TLS 配置文件格式错误!"
- return 1
- fi
- echo -e "${Info} Shadow TLS 配置文件写入成功"
-
- # 显示当前配置的 SNI
- current_sni=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | keys[0]' 2>/dev/null)
- if [[ ! -z "${current_sni}" && "${current_sni}" != "null" ]]; then
- echo -e "${Info} 当前配置的 SNI: ${Green_font_prefix}${current_sni}${Font_color_suffix}"
- fi
- else
- echo -e "${Error} Shadow TLS 配置文件写入失败!"
- return 1
- fi
- }
- read_config(){
- [[ ! -e ${SS_Conf} ]] && echo -e "${Error} Shadowsocks Rust 配置文件不存在!" && exit 1
- port=$(cat ${SS_Conf}|jq -r '.server_port')
- password=$(cat ${SS_Conf}|jq -r '.password')
- cipher=$(cat ${SS_Conf}|jq -r '.method')
- tfo=$(cat ${SS_Conf}|jq -r '.fast_open')
- }
- read_stls_config(){
- [[ ! -e ${STLS_Conf} ]] && echo -e "${Error} Shadow TLS 配置文件不存在!" && exit 1
- stls_port=$(cat ${STLS_Conf}|jq -r '.server.listen' | grep -oE '[0-9]+$')
- stls_password=$(cat ${STLS_Conf}|jq -r '.server.password')
- stls_sni=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | keys[0]')
- stls_fastopen=$(cat ${STLS_Conf}|jq -r '.fastopen')
- stls_strict=$(cat ${STLS_Conf}|jq -r '.strict')
- stls_tls_wildcard_sni=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.wildcard_sni')
- stls_fallback=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.fallback')
- # 读取完整的 dispatch 配置
- stls_dispatch=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map("\"\(.key)\": \"\(.value)\"") | join(",\n ")')
- }
- set_port(){
- while true
- do
- echo -e "${Tip} 本步骤不涉及系统防火墙端口操作,请手动放行相应端口!"
- echo -e "请输入 Shadowsocks Rust 端口 [1-65535]"
- read -e -p "(默认:2525):" port
- [[ -z "${port}" ]] && port="2525"
- echo $((${port}+0)) &>/dev/null
- if [[ $? -eq 0 ]]; then
- if [[ ${port} -ge 1 ]] && [[ ${port} -le 65535 ]]; then
- echo && echo "========================================"
- echo -e "端口:${Red_background_prefix} ${port} ${Font_color_suffix}"
- echo "========================================" && echo
- break
- else
- echo "输入错误, 请输入正确的端口。"
- fi
- else
- echo "输入错误, 请输入正确的端口。"
- fi
- done
- }
- set_tfo(){
- echo -e "是否开启 TCP Fast Open ?
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} 开启 ${Green_font_prefix} 2.${Font_color_suffix} 关闭
- ========================================"
- read -e -p "(默认:1.开启):" tfo
- [[ -z "${tfo}" ]] && tfo="1"
- if [[ ${tfo} == "1" ]]; then
- tfo=true
- enable_systfo
- else
- tfo=false
- fi
- echo && echo "=================================="
- echo -e "TCP Fast Open 开启状态:${Red_background_prefix} ${tfo} ${Font_color_suffix}"
- echo "==================================" && echo
- }
- set_password(){
- echo "请输入 Shadowsocks Rust 密码 [0-9][a-z][A-Z]"
- read -e -p "(默认:随机生成):" password
- # 当用户未输入密码时,执行默认生成逻辑
- if [[ -z "${password}" ]]; then
- # 判断是否为2022系列加密
- if [[ ${cipher} == "2022-blake3-aes-256-gcm" || ${cipher} == "2022-blake3-chacha20-poly1305" ]]; then
- # 2022系列必须使用指定长度的Base64密钥
- echo -e "${Tip} 为 ${cipher} 生成 32 字节 Base64 密钥..."
- password=$(openssl rand -base64 32)
- elif [[ ${cipher} == "2022-blake3-aes-128-gcm" ]]; then
- # 2022系列必须使用指定长度的Base64密钥
- echo -e "${Tip} 为 ${cipher} 生成 16 字节 Base64 密钥..."
- password=$(openssl rand -base64 16)
- else
- # 其他加密方式,生成一个普通的16位字母和数字的随机密码
- echo -e "${Tip} 为 ${cipher} 生成 16 位随机密码 (非Base64)..."
- password=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | head -c 16)
- fi
- fi
- echo && echo "========================================"
- echo -e "密码:${Red_font_prefix} ${password} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_cipher(){
- echo -e "请选择 Shadowsocks Rust 加密方式
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} aes-128-gcm ${Green_font_prefix}(默认)${Font_color_suffix}
- ${Green_font_prefix} 2.${Font_color_suffix} aes-256-gcm ${Green_font_prefix}(推荐)${Font_color_suffix}
- ${Green_font_prefix} 3.${Font_color_suffix} chacha20-ietf-poly1305 ${Green_font_prefix}${Font_color_suffix}
- ${Green_font_prefix} 4.${Font_color_suffix} plain ${Red_font_prefix}(不推荐)${Font_color_suffix}
- ${Green_font_prefix} 5.${Font_color_suffix} none ${Red_font_prefix}(不推荐)${Font_color_suffix}
- ${Green_font_prefix} 6.${Font_color_suffix} table
- ${Green_font_prefix} 7.${Font_color_suffix} aes-128-cfb
- ${Green_font_prefix} 8.${Font_color_suffix} aes-256-cfb
- ${Green_font_prefix} 9.${Font_color_suffix} aes-256-ctr
- ${Green_font_prefix}10.${Font_color_suffix} camellia-256-cfb
- ${Green_font_prefix}11.${Font_color_suffix} rc4-md5
- ${Green_font_prefix}12.${Font_color_suffix} chacha20-ietf
- ========================================
- ${Tip} AEAD 2022 加密(须v1.15.0及以上版本且密码须经过Base64加密)
- ========================================
- ${Green_font_prefix}13.${Font_color_suffix} 2022-blake3-aes-128-gcm ${Green_font_prefix}(推荐)${Font_color_suffix}
- ${Green_font_prefix}14.${Font_color_suffix} 2022-blake3-aes-256-gcm ${Green_font_prefix}(推荐)${Font_color_suffix}
- ${Green_font_prefix}15.${Font_color_suffix} 2022-blake3-chacha20-poly1305
- ========================================
- ${Tip} 如需其它加密方式请手动修改配置文件 !" && echo
- read -e -p "(默认: 1. aes-128-gcm):" cipher
- [[ -z "${cipher}" ]] && cipher="1"
- if [[ ${cipher} == "1" ]]; then
- cipher="aes-128-gcm"
- elif [[ ${cipher} == "2" ]]; then
- cipher="aes-256-gcm"
- elif [[ ${cipher} == "3" ]]; then
- cipher="chacha20-ietf-poly1305"
- elif [[ ${cipher} == "4" ]]; then
- cipher="plain"
- elif [[ ${cipher} == "5" ]]; then
- cipher="none"
- elif [[ ${cipher} == "6" ]]; then
- cipher="table"
- elif [[ ${cipher} == "7" ]]; then
- cipher="aes-128-cfb"
- elif [[ ${cipher} == "8" ]]; then
- cipher="aes-256-cfb"
- elif [[ ${cipher} == "9" ]]; then
- cipher="aes-256-ctr"
- elif [[ ${cipher} == "10" ]]; then
- cipher="camellia-256-cfb"
- elif [[ ${cipher} == "11" ]]; then
- cipher="arc4-md5"
- elif [[ ${cipher} == "12" ]]; then
- cipher="chacha20-ietf"
- elif [[ ${cipher} == "13" ]]; then
- cipher="2022-blake3-aes-128-gcm"
- elif [[ ${cipher} == "14" ]]; then
- cipher="2022-blake3-aes-256-gcm"
- elif [[ ${cipher} == "15" ]]; then
- cipher="2022-blake3-chacha20-poly1305"
- else
- cipher="aes-128-gcm"
- fi
- echo && echo "========================================"
- echo -e "加密:${Red_background_prefix} ${cipher} ${Font_color_suffix}"
- echo "========================================" && echo
- }
- set_config(){
- check_installed_status
- echo && echo -e "你要做什么?
- ========================================
- ${Green_font_prefix}1.${Font_color_suffix} 修改 端口配置
- ${Green_font_prefix}2.${Font_color_suffix} 修改 加密配置
- ${Green_font_prefix}3.${Font_color_suffix} 修改 密码配置
- ${Green_font_prefix}4.${Font_color_suffix} 修改 TFO 配置
- ========================================
- ${Green_font_prefix}5.${Font_color_suffix} 修改 全部配置" && echo
- read -e -p "(默认:取消):" modify
- [[ -z "${modify}" ]] && echo "已取消..." && exit 1
- if [[ "${modify}" == "1" ]]; then
- read_config
- set_port
- cipher=${cipher}
- password=${password}
- tfo=${tfo}
- write_config
- restart
- elif [[ "${modify}" == "2" ]]; then
- read_config
- set_cipher
- port=${port}
- password=${password}
- tfo=${tfo}
- write_config
- restart
- elif [[ "${modify}" == "3" ]]; then
- read_config
- cipher=${cipher}
- set_password
- port=${port}
- tfo=${tfo}
- write_config
- restart
- elif [[ "${modify}" == "4" ]]; then
- read_config
- set_tfo
- cipher=${cipher}
- port=${port}
- password=${password}
- write_config
- restart
- elif [[ "${modify}" == "5" ]]; then
- read_config
- set_port
- set_cipher
- set_password
- set_tfo
- write_config
- restart
- else
- echo -e "${Error} 请输入正确的数字(1-5)" && exit 1
- fi
- }
- install(){
- [[ -e ${SS_File} ]] && echo -e "${Error} 检测到 Shadowsocks Rust 已安装!" && exit 1
- echo -e "${Info} 开始设置 配置..."
- set_port
- set_cipher
- set_password
- set_tfo
- echo -e "${Info} 开始安装/配置 依赖..."
- installation_dependency
- echo -e "${Info} 开始下载/安装..."
- check_new_ver
- download
- echo -e "${Info} 开始安装系统服务脚本..."
- service
- echo -e "${Info} 开始写入 配置文件..."
- write_config
- echo -e "${Info} 所有步骤 安装完毕,开始启动..."
- start
- echo -e "${Info} Shadowsocks Rust 安装完成!"
-
- # 询问是否继续安装 Shadow TLS
- echo && echo -e "${Tip} 是否继续安装 Shadow TLS 流量伪装?"
- read -e -p "(默认: N 不安装) [y/N]: " install_stls_choice
- [[ -z "${install_stls_choice}" ]] && install_stls_choice="n"
-
- if [[ ${install_stls_choice} == [Yy] ]]; then
- echo -e "${Info} 开始安装 Shadow TLS..."
- install_stls_after_ss
- else
- echo -e "${Info} 跳过 Shadow TLS 安装,显示 Shadowsocks Rust 配置..."
- view_ss_only
- fi
- }
- install_stls(){
- [[ -e ${STLS_File} ]] && echo -e "${Error} 检测到 Shadow TLS 已安装!" && exit 1
-
- # 检查 Shadowsocks Rust 是否已安装
- if [[ ! -e ${SS_File} ]]; then
- echo -e "${Error} 检测到 Shadowsocks Rust 尚未安装!"
- echo -e "${Info} Shadow TLS 需要配合 Shadowsocks Rust 使用。"
- echo -e "${Info} 建议先安装 Shadowsocks Rust,再安装 Shadow TLS。"
- echo && read -e -p "是否现在安装 Shadowsocks Rust?[Y/n]:" install_ss_choice
- [[ -z "${install_ss_choice}" ]] && install_ss_choice="Y"
- if [[ ${install_ss_choice} == [Yy] ]]; then
- echo -e "${Info} 开始安装 Shadowsocks Rust..."
- install
- echo -e "${Info} Shadowsocks Rust 安装完成,现在开始安装 Shadow TLS..."
- else
- echo -e "${Info} 已取消安装,返回上级菜单..."
- shadowtls_menu
- return
- fi
- fi
-
- echo -e "${Info} 开始设置 Shadow TLS 配置..."
- read_config # 读取现有 SS 配置
-
- # 使用交互式配置,每项都有默认值
- echo -e "${Info} 请配置 Shadow TLS 参数(可直接回车使用默认值):"
-
- set_stls_port
- set_stls_password
- set_stls_sni
- set_stls_fastopen
- set_stls_strict
- set_stls_tls_wildcard_sni
- set_stls_fallback
- manage_stls_dispatch
-
- echo -e "${Info} 开始下载/安装 Shadow TLS..."
- check_stls_new_ver
- download_stls
- echo -e "${Info} 开始安装 Shadow TLS 服务脚本..."
- service_stls
- echo -e "${Info} 开始写入 Shadow TLS 配置文件..."
- write_stls_config
- echo -e "${Info} Shadow TLS 安装完毕,开始启动..."
- start_stls
- echo -e "${Info} Shadow TLS 安装完成!显示完整配置信息..."
- view_combined_config_with_return
- }
- install_stls_after_ss(){
- echo -e "${Info} 开始设置 Shadow TLS 配置..."
- read_config # 读取现有 SS 配置
-
- # 使用交互式配置,每项都有默认值
- echo -e "${Info} 请配置 Shadow TLS 参数(可直接回车使用默认值):"
-
- set_stls_port
- set_stls_password
- set_stls_sni
- set_stls_fastopen
- set_stls_strict
- set_stls_tls_wildcard_sni
- set_stls_fallback
- manage_stls_dispatch
-
- echo -e "${Info} 开始下载/安装 Shadow TLS..."
- check_stls_new_ver
- download_stls
- echo -e "${Info} 开始安装 Shadow TLS 服务脚本..."
- service_stls
- echo -e "${Info} 开始写入 Shadow TLS 配置文件..."
- write_stls_config
- echo -e "${Info} Shadow TLS 安装完毕,开始启动..."
- start_stls
- echo -e "${Info} Shadow TLS 安装完成!显示完整配置信息..."
- view_combined_config_with_return
- }
- view(){
- check_installed_status
- read_config
- getipv4
- getipv6
- link_qr
- clear && echo
- echo -e "Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " 端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e " TFO :${Green_font_prefix}${tfo}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- [[ ! -z "${link_ipv4}" ]] && echo -e "${link_ipv4}"
- [[ ! -z "${link_ipv6}" ]] && echo -e "${link_ipv6}"
- echo -e "—————————————————————————"
- echo -e "${Info} Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4},${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- else
- echo -e "$(uname -n) = ss, ${ipv6},${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- fi
- echo -e "—————————————————————————"
- echo && echo -n " 按回车键返回主菜单..." && read
- start_menu
- }
- view_ss_only(){
- check_installed_status
- read_config
- getipv4
- getipv6
- link_qr
- clear && echo
- echo -e "Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " 端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e " TFO :${Green_font_prefix}${tfo}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- [[ ! -z "${link_ipv4}" ]] && echo -e "${link_ipv4}"
- [[ ! -z "${link_ipv6}" ]] && echo -e "${link_ipv6}"
- echo -e "—————————————————————————"
- echo -e "${Info} Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4},${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- else
- echo -e "$(uname -n) = ss, ${ipv6},${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- fi
- echo -e "—————————————————————————"
- echo && echo -n " 按回车键返回主菜单..." && read
- start_menu
- }
- view_combined_config(){
- local menu_source="$1" # 接收调用来源参数
- check_installed_status
- read_config
- getipv4
- getipv6
- link_qr
- clear && echo
-
- echo -e "完整配置信息:"
- echo -e "========================================"
-
- # 显示 Shadow TLS + SS 配置
- if [[ -e ${STLS_File} ]]; then
- read_stls_config
- echo -e "${Info} Shadow TLS + Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 服务器:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 服务器:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " Shadow TLS 端口:${Green_font_prefix}${stls_port}${Font_color_suffix}"
- echo -e " Shadow TLS 密码:${Green_font_prefix}${stls_password}${Font_color_suffix}"
- echo -e " Shadow TLS SNI:${Green_font_prefix}${stls_sni}${Font_color_suffix}"
- echo -e " SS 本地端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " SS 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " SS 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- echo -e "${Info} Shadow TLS + SS Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4}, ${stls_port}, encrypt-method=${cipher}, password=${password}, shadow-tls-password=${stls_password}, shadow-tls-sni=${stls_sni}, shadow-tls-version=3, tfo=${tfo}, udp-relay=true, ecn=true, udp-port=${port}"
- else
- echo -e "$(uname -n) = ss, ${ipv6}, ${stls_port}, encrypt-method=${cipher}, password=${password}, shadow-tls-password=${stls_password}, shadow-tls-sni=${stls_sni}, shadow-tls-version=3, tfo=${tfo}, udp-relay=true, ecn=true, udp-port=${port}"
- fi
- echo && echo -e "========================================"
- fi
-
- # 显示纯 SS 配置
- echo -e "${Info} 原始 Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " 端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- [[ ! -z "${link_ipv4}" ]] && echo -e "${link_ipv4}"
- [[ ! -z "${link_ipv6}" ]] && echo -e "${link_ipv6}"
- echo -e "—————————————————————————"
- echo -e "${Info} 原始 SS Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4}, ${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- fi
- echo -e "========================================"
-
- # 根据调用来源返回到相应菜单
- if [[ "$menu_source" == "shadowtls" ]]; then
- echo && echo -n " 按回车键返回 Shadow TLS 菜单..." && read
- shadowtls_menu
- else
- echo && echo -n " 按回车键返回主菜单..." && read
- start_menu
- fi
- }
- view_combined_config_with_return(){
- check_installed_status
- read_config
- getipv4
- getipv6
- link_qr
- clear && echo
-
- echo -e "完整配置信息:"
- echo -e "========================================"
-
- # 显示 Shadow TLS + SS 配置
- if [[ -e ${STLS_File} ]]; then
- read_stls_config
- echo -e "${Info} Shadow TLS + Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 服务器:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 服务器:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " Shadow TLS 端口:${Green_font_prefix}${stls_port}${Font_color_suffix}"
- echo -e " Shadow TLS 密码:${Green_font_prefix}${stls_password}${Font_color_suffix}"
- echo -e " Shadow TLS SNI:${Green_font_prefix}${stls_sni}${Font_color_suffix}"
- echo -e " SS 本地端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " SS 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " SS 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- echo -e "${Info} Shadow TLS + SS Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4}, ${stls_port}, encrypt-method=${cipher}, password=${password}, shadow-tls-password=${stls_password}, shadow-tls-sni=${stls_sni}, shadow-tls-version=3, tfo=${tfo}, ecn=true, udp-relay=true, udp-port=${port}"
- else
- echo -e "$(uname -n) = ss, ${ipv6}, ${stls_port}, encrypt-method=${cipher}, password=${password}, shadow-tls-password=${stls_password}, shadow-tls-sni=${stls_sni}, shadow-tls-version=3, tfo=${tfo}, ecn=true, udp-relay=true, udp-port=${port}"
- fi
- echo && echo -e "========================================"
- fi
-
- # 显示纯 SS 配置
- echo -e "${Info} 原始 Shadowsocks Rust 配置:"
- echo -e "————————————————————————————————————————"
- [[ "${ipv4}" != "IPv4_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv4}${Font_color_suffix}"
- [[ "${ipv6}" != "IPv6_Error" ]] && echo -e " 地址:${Green_font_prefix}${ipv6}${Font_color_suffix}"
- echo -e " 端口:${Green_font_prefix}${port}${Font_color_suffix}"
- echo -e " 密码:${Green_font_prefix}${password}${Font_color_suffix}"
- echo -e " 加密:${Green_font_prefix}${cipher}${Font_color_suffix}"
- echo -e "————————————————————————————————————————"
- [[ ! -z "${link_ipv4}" ]] && echo -e "${link_ipv4}"
- [[ ! -z "${link_ipv6}" ]] && echo -e "${link_ipv6}"
- echo -e "—————————————————————————"
- echo -e "${Info} SS Surge 配置:"
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- echo -e "$(uname -n) = ss, ${ipv4}, ${port}, encrypt-method=${cipher}, password=${password}, tfo=${tfo}, udp-relay=true, ecn=true"
- fi
- echo -e "========================================"
- echo && echo -n " 按回车键继续..." && read
- }
- # 综合 Shadow TLS 配置函数
- set_stls_config(){
- check_stls_installed_status
- read_config
- read_stls_config
-
- echo && echo -e "你要修改哪项 Shadow TLS 配置?
- ========================================
- ${Green_font_prefix}1.${Font_color_suffix} 修改 端口配置
- ${Green_font_prefix}2.${Font_color_suffix} 修改 密码配置
- ${Green_font_prefix}3.${Font_color_suffix} 修改 Shadow TLS SNI 域名
- ${Green_font_prefix}4.${Font_color_suffix} 修改 FastOpen 配置
- ${Green_font_prefix}5.${Font_color_suffix} 修改 Strict 模式配置
- ${Green_font_prefix}6.${Font_color_suffix} 修改 TLS Wildcard SNI 配置
- ${Green_font_prefix}7.${Font_color_suffix} 修改 回退域名配置
- ${Green_font_prefix}8.${Font_color_suffix} 管理 Dispatch 分发配置
- ========================================
- ${Green_font_prefix}9.${Font_color_suffix} 修改 全部配置" && echo
- read -e -p "(默认:取消):" modify
- [[ -z "${modify}" ]] && echo "已取消..." && return
-
- case "${modify}" in
- 1)
- set_stls_port
- write_stls_config
- restart_stls
- ;;
- 2)
- set_stls_password
- write_stls_config
- restart_stls
- ;;
- 3)
- set_stls_sni
- write_stls_config
- restart_stls
- ;;
- 4)
- set_stls_fastopen
- write_stls_config
- restart_stls
- ;;
- 5)
- set_stls_strict
- write_stls_config
- restart_stls
- ;;
- 6)
- set_stls_tls_wildcard_sni
- write_stls_config
- restart_stls
- ;;
- 7)
- set_stls_fallback
- write_stls_config
- restart_stls
- ;;
- 8)
- manage_stls_dispatch
- if [[ ! -z "${stls_dispatch}" ]]; then
- write_stls_config
- restart_stls
- fi
- ;;
- 9)
- set_stls_port
- set_stls_password
- set_stls_sni
- set_stls_fastopen
- set_stls_strict
- set_stls_tls_wildcard_sni
- set_stls_fallback
- manage_stls_dispatch
- write_stls_config
- restart_stls
- ;;
- *)
- echo -e "${Error} 请输入正确的数字(1-9)"
- set_stls_config
- ;;
- esac
- }
- # Dispatch 管理的简化版本
- manage_stls_dispatch(){
- echo -e "${Info} 当前 dispatch 配置:"
- if [[ -e ${STLS_Conf} ]]; then
- echo -e "${Green_font_prefix}$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map(" \(.key) -> \(.value)") | join("\n")')${Font_color_suffix}"
- else
- echo -e " ${stls_sni} -> 1.1.1.1:443"
- echo -e " captive.apple.com -> captive.apple.com:443"
- fi
-
- echo && echo -e "是否需要修改 dispatch 配置?
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} 使用默认配置(推荐)
- ${Green_font_prefix} 2.${Font_color_suffix} 自定义配置所有条目
- ========================================"
- read -e -p "(默认:1.使用默认):" dispatch_choice
- [[ -z "${dispatch_choice}" ]] && dispatch_choice="1"
-
- if [[ "${dispatch_choice}" == "1" ]]; then
- # 使用默认配置,确保使用当前设置的 SNI
- echo -e "${Info} 使用默认 dispatch 配置,SNI: ${stls_sni}"
- # 不设置 stls_dispatch,让 write_stls_config 使用默认逻辑
- stls_dispatch=""
- elif [[ "${dispatch_choice}" == "2" ]]; then
- echo -e "${Info} 重新配置 dispatch 条目"
- echo "请输入 dispatch 配置 (每行格式: 域名:目标地址,回车结束):"
- echo "示例: cloudflare.com:1.1.1.1:443"
-
- local dispatch_entries=""
- local line_count=0
- while true; do
- read -e -p "条目 $((line_count+1)) (直接回车结束):" dispatch_entry
- if [[ -z "${dispatch_entry}" ]]; then
- break
- fi
-
- if [[ "${dispatch_entry}" =~ ^([^:]+):(.+)$ ]]; then
- local sni="${BASH_REMATCH[1]}"
- local target="${BASH_REMATCH[2]}"
-
- if [[ ${line_count} -gt 0 ]]; then
- dispatch_entries="${dispatch_entries},
- "
- fi
- dispatch_entries="${dispatch_entries}\"${sni}\": \"${target}\""
- line_count=$((line_count+1))
- else
- echo -e "${Error} 格式错误,请使用格式: 域名:目标地址"
- fi
- done
-
- if [[ ${line_count} -gt 0 ]]; then
- stls_dispatch="${dispatch_entries}"
- echo -e "${Info} 已配置 ${line_count} 个 dispatch 条目"
- else
- echo -e "${Info} 没有输入条目,使用默认 dispatch 配置"
- # 不设置 stls_dispatch,让 write_stls_config 使用默认逻辑
- stls_dispatch=""
- fi
- fi
- }
- # 增强版 Dispatch 管理(支持单条增删改)
- manage_stls_dispatch_advanced(){
- echo -e "${Info} 当前 dispatch 配置:"
- if [[ -e ${STLS_Conf} ]]; then
- echo -e "${Green_font_prefix}$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map(" \(.key) -> \(.value)") | join("\n")')${Font_color_suffix}"
- else
- echo -e " ${stls_sni} -> 1.1.1.1:443"
- echo -e " captive.apple.com -> captive.apple.com:443"
- fi
-
- echo && echo -e "请选择 dispatch 管理操作:
- ========================================
- ${Green_font_prefix} 1.${Font_color_suffix} 保持当前配置
- ${Green_font_prefix} 2.${Font_color_suffix} 添加新条目
- ${Green_font_prefix} 3.${Font_color_suffix} 删除指定条目
- ${Green_font_prefix} 4.${Font_color_suffix} 修改指定条目
- ${Green_font_prefix} 5.${Font_color_suffix} 重新配置所有条目
- ========================================"
- read -e -p "(默认:1.保持当前):" dispatch_choice
- [[ -z "${dispatch_choice}" ]] && dispatch_choice="1"
-
- case "${dispatch_choice}" in
- 1)
- echo -e "${Info} 保持当前配置"
- ;;
- 2)
- add_dispatch_entry
- ;;
- 3)
- delete_dispatch_entry
- ;;
- 4)
- modify_dispatch_entry
- ;;
- 5)
- reconfigure_all_dispatch
- ;;
- *)
- echo -e "${Error} 输入错误,保持当前配置"
- ;;
- esac
- }
- # 添加 dispatch 条目
- add_dispatch_entry(){
- echo -e "${Info} 添加新的 dispatch 条目"
- read -e -p "请输入域名 (如: example.com):" new_sni
- if [[ -z "${new_sni}" ]]; then
- echo -e "${Error} 域名不能为空"
- return
- fi
-
- read -e -p "请输入目标地址 (如: 1.1.1.1:443):" new_target
- if [[ -z "${new_target}" ]]; then
- echo -e "${Error} 目标地址不能为空"
- return
- fi
-
- # 获取当前 dispatch 配置
- if [[ -e ${STLS_Conf} ]]; then
- current_dispatch=$(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map("\"\(.key)\": \"\(.value)\"") | join(",\n ")')
- stls_dispatch="${current_dispatch},
- \"${new_sni}\": \"${new_target}\""
- else
- stls_dispatch="\"${stls_sni}\": \"1.1.1.1:443\",
- \"captive.apple.com\": \"captive.apple.com:443\",
- \"${new_sni}\": \"${new_target}\""
- fi
-
- echo -e "${Info} 已添加条目: ${new_sni} -> ${new_target}"
- }
- # 删除 dispatch 条目
- delete_dispatch_entry(){
- if [[ ! -e ${STLS_Conf} ]]; then
- echo -e "${Error} 配置文件不存在"
- return
- fi
-
- echo -e "${Info} 当前 dispatch 条目:"
- # 显示带编号的列表
- local domains=($(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | keys[]'))
- local targets=($(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map(.value) | .[]'))
-
- if [[ ${#domains[@]} -eq 0 ]]; then
- echo -e "${Error} 没有可删除的条目"
- return
- fi
-
- for i in "${!domains[@]}"; do
- echo -e " ${Green_font_prefix}$((i+1)).${Font_color_suffix} ${domains[i]} -> ${targets[i]}"
- done
-
- read -e -p "请输入要删除的条目编号 (1-${#domains[@]}):" del_num
- if [[ -z "${del_num}" ]] || [[ ${del_num} -lt 1 ]] || [[ ${del_num} -gt ${#domains[@]} ]]; then
- echo -e "${Error} 输入的编号无效"
- return
- fi
-
- # 重新构建 dispatch 配置,排除删除的条目
- local del_domain="${domains[$((del_num-1))]}"
- local new_entries=""
- local count=0
-
- for i in "${!domains[@]}"; do
- if [[ "${domains[i]}" != "${del_domain}" ]]; then
- if [[ ${count} -gt 0 ]]; then
- new_entries="${new_entries},
- "
- fi
- new_entries="${new_entries}\"${domains[i]}\": \"${targets[i]}\""
- count=$((count+1))
- fi
- done
-
- if [[ ${count} -eq 0 ]]; then
- # 如果删除后没有条目,使用默认配置
- stls_dispatch="\"${stls_sni}\": \"1.1.1.1:443\",
- \"captive.apple.com\": \"captive.apple.com:443\""
- else
- stls_dispatch="${new_entries}"
- fi
-
- echo -e "${Info} 已删除条目: ${del_domain}"
- }
- # 修改 dispatch 条目
- modify_dispatch_entry(){
- if [[ ! -e ${STLS_Conf} ]]; then
- echo -e "${Error} 配置文件不存在"
- return
- fi
-
- echo -e "${Info} 当前 dispatch 条目:"
- # 显示带编号的列表
- local domains=($(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | keys[]'))
- local targets=($(cat ${STLS_Conf}|jq -r '.server.tls_addr.dispatch | to_entries | map(.value) | .[]'))
-
- if [[ ${#domains[@]} -eq 0 ]]; then
- echo -e "${Error} 没有可修改的条目"
- return
- fi
-
- for i in "${!domains[@]}"; do
- echo -e " ${Green_font_prefix}$((i+1)).${Font_color_suffix} ${domains[i]} -> ${targets[i]}"
- done
-
- read -e -p "请输入要修改的条目编号 (1-${#domains[@]}):" mod_num
- if [[ -z "${mod_num}" ]] || [[ ${mod_num} -lt 1 ]] || [[ ${mod_num} -gt ${#domains[@]} ]]; then
- echo -e "${Error} 输入的编号无效"
- return
- fi
-
- local mod_domain="${domains[$((mod_num-1))]}"
- local mod_target="${targets[$((mod_num-1))]}"
-
- echo -e "${Info} 当前条目: ${mod_domain} -> ${mod_target}"
- read -e -p "请输入新的域名 (直接回车保持不变):" new_domain
- read -e -p "请输入新的目标地址 (直接回车保持不变):" new_target
-
- [[ -z "${new_domain}" ]] && new_domain="${mod_domain}"
- [[ -z "${new_target}" ]] && new_target="${mod_target}"
-
- # 重新构建 dispatch 配置
- local new_entries=""
- for i in "${!domains[@]}"; do
- if [[ ${i} -gt 0 ]]; then
- new_entries="${new_entries},
- "
- fi
-
- if [[ ${i} -eq $((mod_num-1)) ]]; then
- new_entries="${new_entries}\"${new_domain}\": \"${new_target}\""
- else
- new_entries="${new_entries}\"${domains[i]}\": \"${targets[i]}\""
- fi
- done
-
- stls_dispatch="${new_entries}"
- echo -e "${Info} 已修改条目: ${mod_domain} -> ${mod_target} => ${new_domain} -> ${new_target}"
- }
- # 重新配置所有 dispatch 条目
- reconfigure_all_dispatch(){
- echo -e "${Info} 重新配置所有 dispatch 条目"
- echo "请输入 dispatch 配置 (每行格式: 域名:目标地址,回车结束):"
- echo "示例: cloudflare.com:1.1.1.1:443"
-
- local dispatch_entries=""
- local line_count=0
- while true; do
- read -e -p "条目 $((line_count+1)) (直接回车结束):" dispatch_entry
- if [[ -z "${dispatch_entry}" ]]; then
- break
- fi
-
- if [[ "${dispatch_entry}" =~ ^([^:]+):(.+)$ ]]; then
- local sni="${BASH_REMATCH[1]}"
- local target="${BASH_REMATCH[2]}"
-
- if [[ ${line_count} -gt 0 ]]; then
- dispatch_entries="${dispatch_entries},
- "
- fi
- dispatch_entries="${dispatch_entries}\"${sni}\": \"${target}\""
- line_count=$((line_count+1))
- else
- echo -e "${Error} 格式错误,请使用格式: 域名:目标地址"
- fi
- done
-
- if [[ ${line_count} -gt 0 ]]; then
- stls_dispatch="${dispatch_entries}"
- echo -e "${Info} 已配置 ${line_count} 个 dispatch 条目"
- else
- echo -e "${Info} 使用默认 dispatch 配置"
- stls_dispatch="\"${stls_sni}\": \"1.1.1.1:443\",
- \"captive.apple.com\": \"captive.apple.com:443\""
- fi
- }
- start(){
- check_installed_status
- check_status
- if [[ "$status" == "running" ]]; then
- echo -e "${Info} Shadowsocks Rust 已在运行!"
- else
- systemctl start ss-rust
- check_status
- if [[ "$status" == "running" ]]; then
- echo -e "${Info} Shadowsocks Rust 启动成功!"
- else
- echo -e "${Error} Shadowsocks Rust 启动失败!"
- exit 1
- fi
- fi
- sleep 3s
- }
- start_stls(){
- check_stls_installed_status
- check_stls_status
- if [[ "$stls_status" == "running" ]]; then
- echo -e "${Info} Shadow TLS 已在运行!"
- else
- systemctl start shadowtls
- check_stls_status
- if [[ "$stls_status" == "running" ]]; then
- echo -e "${Info} Shadow TLS 启动成功!"
- else
- echo -e "${Error} Shadow TLS 启动失败!"
- exit 1
- fi
- fi
- sleep 3s
- }
- stop(){
- check_installed_status
- check_status
- [[ !"$status" == "running" ]] && echo -e "${Error} Shadowsocks Rust 没有运行,请检查!" && exit 1
- systemctl stop ss-rust
- sleep 3s
- start_menu
- }
- stop_stls(){
- check_stls_installed_status
- check_stls_status
- [[ !"$stls_status" == "running" ]] && echo -e "${Error} Shadow TLS 没有运行,请检查!" && exit 1
- systemctl stop shadowtls
- sleep 3s
- }
- restart(){
- check_installed_status
- systemctl restart ss-rust
- echo -e "${Info} Shadowsocks Rust 重启完毕 !"
- sleep 3s
- start_menu
- }
- restart_stls(){
- check_stls_installed_status
- systemctl restart shadowtls
- echo -e "${Info} Shadow TLS 重启完毕 !"
- sleep 3s
- }
- update(){
- check_installed_status
- check_new_ver
- check_ver_comparison
- echo -e "${Info} Shadowsocks Rust 更新完毕!"
- sleep 3s
- start_menu
- }
- update_stls(){
- check_stls_installed_status
- check_stls_new_ver
- check_stls_ver_comparison
- echo -e "${Info} Shadow TLS 更新完毕!"
- sleep 3s
- }
- # 脚本更新函数
- update_sh(){
- echo -e "当前版本为 [ ${sh_ver} ],开始检测最新版本..."
- sh_new_ver=$(wget --no-check-certificate -qO- "https://raw.githubusercontent.com/xOS/Shadowsocks-Rust/master/ss-rust.sh"|grep 'sh_ver="'|awk -F "=" '{print $NF}'|sed 's/\"//g'|head -1)
- [[ -z ${sh_new_ver} ]] && echo -e "${Error} 检测最新版本失败 !" && start_menu
- if [[ ${sh_new_ver} != ${sh_ver} ]]; then
- echo -e "发现新版本[ ${sh_new_ver} ],是否更新?[Y/n]"
- read -p "(默认:y):" yn
- [[ -z "${yn}" ]] && yn="y"
- if [[ ${yn} == [Yy] ]]; then
- wget -O ss-rust.sh --no-check-certificate https://raw.githubusercontent.com/xOS/Shadowsocks-Rust/master/ss-rust.sh && chmod +x ss-rust.sh
- echo -e "脚本已更新为最新版本[ ${sh_new_ver} ]!"
- echo -e "3s后执行新脚本"
- sleep 3s
- bash ss-rust.sh
- else
- echo && echo " 已取消..." && echo
- sleep 3s
- start_menu
- fi
- else
- echo -e "当前已是最新版本[ ${sh_new_ver} ] !"
- sleep 3s
- start_menu
- fi
- sleep 3s
- bash ss-rust.sh
- }
- uninstall(){
- check_installed_status
- echo "确定要卸载 Shadowsocks Rust ? (y/N)"
- echo
- read -e -p "(默认:n):" unyn
- [[ -z ${unyn} ]] && unyn="n"
- if [[ ${unyn} == [Yy] ]]; then
- check_status
- [[ "$status" == "running" ]] && systemctl stop ss-rust
- systemctl disable ss-rust
- rm -rf "${SS_Folder}"
- rm -rf "${SS_File}"
- echo && echo "Shadowsocks Rust 卸载完成!" && echo
- else
- echo && echo "卸载已取消..." && echo
- fi
- sleep 3s
- start_menu
- }
- uninstall_stls(){
- check_stls_installed_status
- echo "确定要卸载 Shadow TLS ? (y/N)"
- echo
- read -e -p "(默认:n):" unyn
- [[ -z ${unyn} ]] && unyn="n"
- if [[ ${unyn} == [Yy] ]]; then
- check_stls_status
- [[ "$stls_status" == "running" ]] && systemctl stop shadowtls
- systemctl disable shadowtls
- rm -rf "${STLS_Folder}"
- rm -rf "${STLS_File}"
- rm -f "/etc/systemd/system/shadowtls.service"
- systemctl daemon-reload
- echo && echo "Shadow TLS 卸载完成!" && echo
- else
- echo && echo "卸载已取消..." && echo
- fi
- sleep 3s
- }
- getipv4(){
- ipv4=$(wget -qO- -4 -t1 -T2 ipinfo.io/ip)
- if [[ -z "${ipv4}" ]]; then
- ipv4=$(wget -qO- -4 -t1 -T2 api.ip.sb/ip)
- if [[ -z "${ipv4}" ]]; then
- ipv4=$(wget -qO- -4 -t1 -T2 members.3322.org/dyndns/getip)
- if [[ -z "${ipv4}" ]]; then
- ipv4="IPv4_Error"
- fi
- fi
- fi
- }
- getipv6(){
- ipv6=$(wget -qO- -6 -t1 -T2 ifconfig.co)
- if [[ -z "${ipv6}" ]]; then
- ipv6="IPv6_Error"
- fi
- }
- urlsafe_base64(){
- date=$(echo -n "$1"|base64|sed ':a;N;s/\n/ /g;ta'|sed 's/ //g;s/=//g;s/+/-/g;s/\//_/g')
- echo -e "${date}"
- }
- link_qr(){
- if [[ "${ipv4}" != "IPv4_Error" ]]; then
- SSbase64=$(urlsafe_base64 "${cipher}:${password}@${ipv4}:${port}")
- SSurl="ss://${SSbase64}"
- SSQRcode="https://cli.im/api/qrcode/code?text=${SSurl}"
- link_ipv4=" 链接 [IPv4]:${Red_font_prefix}${SSurl}${Font_color_suffix} \n 二维码[IPv4]:${Red_font_prefix}${SSQRcode}${Font_color_suffix}"
- fi
- if [[ "${ipv6}" != "IPv6_Error" ]]; then
- SSbase64=$(urlsafe_base64 "${cipher}:${password}@${ipv6}:${port}")
- SSurl="ss://${SSbase64}"
- SSQRcode="https://cli.im/api/qrcode/code?text=${SSurl}"
- link_ipv6=" 链接 [IPv6]:${Red_font_prefix}${SSurl}${Font_color_suffix} \n 二维码[IPv6]:${Red_font_prefix}${SSQRcode}${Font_color_suffix}"
- fi
- }
- before_start_menu(){
- echo && echo -n " 任意键继续..." && read
- start_menu
- }
- before_shadowtls_menu(){
- echo && echo -n " 任意键继续..." && read
- shadowtls_menu
- }
- # Shadow TLS 状态和版本检查函数
- check_stls_installed_status(){
- [[ ! -e ${STLS_File} ]] && echo -e "${Error} Shadow TLS 没有安装,请检查!" && exit 1
- }
- check_stls_status(){
- stls_status=`systemctl status shadowtls | grep Active | awk '{print $3}' | cut -d "(" -f2 | cut -d ")" -f1`
- }
- check_stls_new_ver(){
- stls_new_ver=$(wget -qO- https://api.github.com/repos/ihciah/shadow-tls/releases| jq -r '[.[] | select(.prerelease == false) | select(.draft == false) | .tag_name] | .[0]')
- [[ -z ${stls_new_ver} ]] && echo -e "${Error} Shadow TLS 最新版本获取失败!" && exit 1
- echo -e "${Info} 检测到 Shadow TLS 最新版本为 [ ${stls_new_ver} ]"
- }
- check_stls_ver_comparison(){
- stls_now_ver=$(cat ${STLS_Now_ver_File})
- if [[ "${stls_now_ver}" != "${stls_new_ver}" ]]; then
- echo -e "${Info} 发现 Shadow TLS 已有新版本 [ ${stls_new_ver} ],旧版本 [ ${stls_now_ver} ]"
- read -e -p "是否更新 ? [Y/n]:" yn
- [[ -z "${yn}" ]] && yn="y"
- if [[ $yn == [Yy] ]]; then
- check_stls_status
- \cp "${STLS_Conf}" "/tmp/stls_config.json"
- download_stls
- mv -f "/tmp/stls_config.json" "${STLS_Conf}"
- restart_stls
- fi
- else
- echo -e "${Info} 当前 Shadow TLS 已是最新版本 [ ${stls_new_ver} ] !" && exit 1
- fi
- }
- # Shadow TLS 专用菜单
- shadowtls_menu(){
- check_root
- check_sys
- sys_arch
-
- # 检查 Shadow TLS 安装状态
- if [[ -e ${STLS_File} ]]; then
- check_stls_status
- if [[ "$stls_status" == "running" ]]; then
- stls_status_show="${Green_font_prefix}已安装${Font_color_suffix} 且 ${Green_font_prefix}运行中${Font_color_suffix}"
- else
- stls_status_show="${Green_font_prefix}已安装${Font_color_suffix} 但 ${Yellow_font_prefix}未运行${Font_color_suffix}"
- fi
- else
- stls_status_show="${Red_font_prefix}未安装${Font_color_suffix}"
- fi
-
- clear
- echo -e "Shadow TLS 管理菜单 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix}
-
- ==================状态==================
- Shadow TLS : [${stls_status_show}]
- ========================================
- ${Green_font_prefix}0.${Font_color_suffix} 更新脚本
- ==================菜单==================
- ${Green_font_prefix}1.${Font_color_suffix} 安装 Shadow TLS
- ${Green_font_prefix}2.${Font_color_suffix} 更新 Shadow TLS
- ${Green_font_prefix}3.${Font_color_suffix} 卸载 Shadow TLS
- ————————————————————————————————————————
- ${Green_font_prefix}4.${Font_color_suffix} 启动 Shadow TLS
- ${Green_font_prefix}5.${Font_color_suffix} 停止 Shadow TLS
- ${Green_font_prefix}6.${Font_color_suffix} 重启 Shadow TLS
- ————————————————————————————————————————
- ${Green_font_prefix}7.${Font_color_suffix} 修改 Shadow TLS 配置
- ${Green_font_prefix}8.${Font_color_suffix} 查看 Shadow TLS 配置
- ${Green_font_prefix}9.${Font_color_suffix} 查看 Shadow TLS 状态
- ————————————————————————————————————————
- ${Green_font_prefix}10.${Font_color_suffix} 查看完整配置信息
- ${Green_font_prefix}11.${Font_color_suffix} 返回主菜单
- ————————————————————————————————————————
- ${Green_font_prefix}00.${Font_color_suffix} 退出脚本
- ========================================" && echo
- read -e -p " 请输入数字 [0-11]:" stls_num
- case "$stls_num" in
- 1)
- install_stls
- shadowtls_menu
- ;;
- 2)
- update_stls
- shadowtls_menu
- ;;
- 3)
- uninstall_stls
- shadowtls_menu
- ;;
- 4)
- start_stls
- shadowtls_menu
- ;;
- 5)
- stop_stls
- shadowtls_menu
- ;;
- 6)
- restart_stls
- shadowtls_menu
- ;;
- 7)
- set_stls_config
- shadowtls_menu
- ;;
- 8)
- view_stls_only
- ;;
- 9)
- view_stls_status
- ;;
- 10)
- view_combined_config shadowtls
- ;;
- 11)
- start_menu
- ;;
- 0)
- update_sh
- ;;
- 00)
- exit 1
- ;;
- *)
- echo -e "${Error} 请输入正确数字 [0-11] (退出输入00)"
- sleep 5s
- shadowtls_menu
- ;;
- esac
- }
- # 查看 Shadowsocks Rust 状态函数
- view_ss_status(){
- check_installed_status
-
- echo -e "${Info} 正在获取 Shadowsocks Rust 状态信息..."
- echo
- echo "=================================="
- echo -e " Shadowsocks Rust 服务状态"
- echo "=================================="
-
- systemctl status ss-rust
-
- echo "=================================="
- echo
- read -e -p "按回车键返回主菜单..."
- start_menu
- }
- # 查看 Shadow TLS 状态函数
- view_stls_status(){
- check_stls_installed_status
-
- echo -e "${Info} 正在获取 Shadow TLS 状态信息..."
- echo
- echo "=================================="
- echo -e " Shadow TLS 服务状态"
- echo "=================================="
-
- systemctl status shadowtls
-
- echo "=================================="
- echo
- read -e -p "按回车键返回 Shadow TLS 菜单..."
- shadowtls_menu
- }
- # 查看 Shadow TLS 配置函数
- view_stls_only(){
- check_stls_installed_status
- echo -e "${Info} 正在获取 Shadow TLS 配置信息..."
- echo
- echo "=================================="
- echo -e " Shadow TLS 配置信息"
- echo "=================================="
-
- if [[ -f "$STLS_Conf" ]]; then
- cat "$STLS_Conf"
- else
- echo -e "${Error} Shadow TLS 配置文件不存在!"
- fi
-
- echo "=================================="
- echo
- read -e -p "按回车键返回 Shadow TLS 菜单..."
- shadowtls_menu
- }
- # 主菜单函数
- start_menu(){
- echo -e "${Info} 正在启动 Shadowsocks Rust 管理脚本..."
- check_root
- echo -e "${Info} 权限检查完成,正在检测系统..."
- check_sys
- echo -e "${Info} 系统检测完成,正在检测架构..."
- sys_arch
- echo -e "${Info} 架构检测完成,正在检查服务状态..."
-
- # 检查安装状态
- if [[ -e ${SS_File} ]]; then
- check_status
- if [[ "$status" == "running" ]]; then
- ss_status_show="${Green_font_prefix}已安装${Font_color_suffix} 且 ${Green_font_prefix}运行中${Font_color_suffix}"
- else
- ss_status_show="${Green_font_prefix}已安装${Font_color_suffix} 但 ${Yellow_font_prefix}未运行${Font_color_suffix}"
- fi
- else
- ss_status_show="${Red_font_prefix}未安装${Font_color_suffix}"
- fi
-
- # 检查 Shadow TLS 安装状态
- if [[ -e ${STLS_File} ]]; then
- check_stls_status
- if [[ "$stls_status" == "running" ]]; then
- stls_status_show="${Green_font_prefix}已安装${Font_color_suffix} 且 ${Green_font_prefix}运行中${Font_color_suffix}"
- else
- stls_status_show="${Green_font_prefix}已安装${Font_color_suffix} 但 ${Yellow_font_prefix}未运行${Font_color_suffix}"
- fi
- else
- stls_status_show="${Red_font_prefix}未安装${Font_color_suffix}"
- fi
-
- clear
- echo -e "Shadowsocks Rust 管理脚本 ${Red_font_prefix}[v${sh_ver}]${Font_color_suffix}
-
- ==================状态==================
- Shadowsocks Rust : [${ss_status_show}]
- Shadow TLS : [${stls_status_show}]
- ========================================
- ${Green_font_prefix}0.${Font_color_suffix} 更新脚本
- ==================菜单==================
- ${Green_font_prefix}1.${Font_color_suffix} 安装 Shadowsocks Rust
- ${Green_font_prefix}2.${Font_color_suffix} 更新 Shadowsocks Rust
- ${Green_font_prefix}3.${Font_color_suffix} 卸载 Shadowsocks Rust
- ————————————————————————————————————————
- ${Green_font_prefix}4.${Font_color_suffix} 启动 Shadowsocks Rust
- ${Green_font_prefix}5.${Font_color_suffix} 停止 Shadowsocks Rust
- ${Green_font_prefix}6.${Font_color_suffix} 重启 Shadowsocks Rust
- ————————————————————————————————————————
- ${Green_font_prefix}7.${Font_color_suffix} 配置 Shadowsocks Rust 相关
- ${Green_font_prefix}8.${Font_color_suffix} 查看 Shadowsocks Rust 配置
- ${Green_font_prefix}9.${Font_color_suffix} 查看 Shadowsocks Rust 状态
- ========================================
- ${Green_font_prefix}10.${Font_color_suffix} 配置 Shadow TLS 相关
- ${Green_font_prefix}11.${Font_color_suffix} 查看完整配置信息
- ————————————————————————————————————————
- ${Green_font_prefix}00.${Font_color_suffix} 退出脚本
- ========================================" && echo
- read -e -p " 请输入数字 [0-11]:" num
- case "$num" in
- 1)
- install
- ;;
- 2)
- update
- start_menu
- ;;
- 3)
- uninstall
- start_menu
- ;;
- 4)
- start
- start_menu
- ;;
- 5)
- stop
- start_menu
- ;;
- 6)
- restart
- start_menu
- ;;
- 7)
- set_config
- ;;
- 8)
- view
- ;;
- 9)
- view_ss_status
- ;;
- 10)
- shadowtls_menu
- ;;
- 11)
- view_combined_config
- ;;
- 0)
- update_sh
- ;;
- 00)
- exit 1
- ;;
- *)
- echo -e "${Error} 请输入正确数字 [0-11] (退出输入00)"
- sleep 5s
- start_menu
- ;;
- esac
- }
- # 脚本执行入口
- start_menu
|