diff --git a/scripts/init.sh b/scripts/init.sh index 1245d3fc..32af99aa 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -222,9 +222,9 @@ fi #修饰文件及版本号 command -v bash >/dev/null 2>&1 && shtype=bash [ -x /bin/ash ] && shtype=ash -for file in start.sh task.sh menu.sh; do +for file in start.sh menus/task.sh menu.sh; do sed -i "s|/bin/sh|/bin/$shtype|" ${CRASHDIR}/${file} 2>/dev/null - chmod 755 ${CRASHDIR}/${file} 2>/dev/null + chmod +x ${CRASHDIR}/${file} 2>/dev/null done setconfig versionsh_l $version #生成用于执行启动服务的变量文件 @@ -339,7 +339,6 @@ for file in fake_ip_filter mac web_save servers.list fake_ip_filter.list fallbac mv -f ${CRASHDIR}/$file ${CRASHDIR}/configs/$file 2>/dev/null done #配置文件改名 -mv -f ${CRASHDIR}/mark ${CRASHDIR}/configs/ShellCrash.cfg 2>/dev/null mv -f ${CRASHDIR}/configs/ShellClash.cfg ${CRASHDIR}/configs/ShellCrash.cfg 2>/dev/null #数据库改名 mv -f ${CRASHDIR}/geosite.dat ${CRASHDIR}/GeoSite.dat 2>/dev/null @@ -355,7 +354,7 @@ mv -f ${CRASHDIR}/clash ${CRASHDIR}/CrashCore 2>/dev/null for file in dropbear_rsa_host_key authorized_keys tun.ko ShellDDNS.sh; do mv -f ${CRASHDIR}/$file ${CRASHDIR}/tools/$file 2>/dev/null done -for file in cron task.sh task.list; do +for file in cron task.list; do mv -f ${CRASHDIR}/$file ${CRASHDIR}/task/$file 2>/dev/null done #旧版文件清理 @@ -364,9 +363,10 @@ sed -i '/shellclash/d' /etc/passwd sed -i '/shellclash/d' /etc/group rm -rf /etc/init.d/clash rm -rf ${CRASHDIR}/rules +rm -rf "$CRASHDIR/task/task.sh" [ "$systype" = "mi_snapshot" -a "$CRASHDIR" != '/data/clash' ] && rm -rf /data/clash for file in CrashCore clash.sh getdate.sh core.new clashservice log shellcrash.service mark? mark.bak; do - rm -rf ${CRASHDIR}/$file + rm -rf "$CRASHDIR/$file" done #旧版变量改名 sed -i "s/clashcore/crashcore/g" $configpath diff --git a/scripts/libs/check_cmd.sh b/scripts/libs/check_cmd.sh new file mode 100644 index 00000000..8a1319a5 --- /dev/null +++ b/scripts/libs/check_cmd.sh @@ -0,0 +1,7 @@ +ckcmd() { + if command -v sh >/dev/null 2>&1;then + command -v "$1" >/dev/null 2>&1 + else + type "$1" >/dev/null 2>&1 + fi +} diff --git a/scripts/libs/check_dir_avail.sh b/scripts/libs/check_dir_avail.sh new file mode 100644 index 00000000..0a2f3e45 --- /dev/null +++ b/scripts/libs/check_dir_avail.sh @@ -0,0 +1,5 @@ +#检查目录剩余空间——$1:目标路径 $2:-h参数 +dir_avail(){ + df -h >/dev/null 2>&1 && h="$2" + df $h "$1" |awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' |grep -E 'Ava|可用' |awk '{print $2}' +} \ No newline at end of file diff --git a/scripts/libs/set_config.sh b/scripts/libs/set_config.sh new file mode 100644 index 00000000..bdb069da --- /dev/null +++ b/scripts/libs/set_config.sh @@ -0,0 +1,9 @@ +#参数1代表变量名,参数2代表变量值,参数3即文件路径 +setconfig() { + [ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}" + if grep -q "^${1}=" "$configpath"; then + sed -i "s#^${1}=.*#^${1}=${2}#g" "$configpath" + else + printf '%s=%s\n' "$1" "$2" >>"$configpath" + fi +} \ No newline at end of file diff --git a/scripts/menu.sh b/scripts/menu.sh index a86824b6..3becad57 100644 --- a/scripts/menu.sh +++ b/scripts/menu.sh @@ -5,39 +5,53 @@ CRASHDIR=$( cd $(dirname $0) pwd ) -CFG_PATH=${CRASHDIR}/configs/ShellCrash.cfg -YAMLSDIR=${CRASHDIR}/yamls -JSONSDIR=${CRASHDIR}/jsons +CFG_PATH="$CRASHDIR"/configs/ShellCrash.cfg +YAMLSDIR="$CRASHDIR"/yamls +JSONSDIR="$CRASHDIR"/jsons #加载执行目录,失败则初始化 -. ${CRASHDIR}/configs/command.env 2>/dev/null -[ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . ${CRASHDIR}/init.sh >/dev/null 2>&1 -[ ! -f ${TMPDIR} ] && mkdir -p ${TMPDIR} +. "$CRASHDIR"/configs/command.env 2>/dev/null +[ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1 +[ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR" [ -n "$(tar --help 2>&1 | grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容 -#读取配置相关 -setconfig() { - #参数1代表变量名,参数2代表变量值,参数3即文件路径 - [ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}" - if grep -q "^${1}=" "$configpath"; then - sed -i "s#^${1}=.*#${1}=${2}#g" "$configpath" - else - printf '%s=%s\n' "$1" "$2" >>"$configpath" - fi +#加载工具 +. "$CRASHDIR"/libs/set_config.sh +. "$CRASHDIR"/libs/check_cmd.sh +errornum() { + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的字母或数字!\033[0m" } -ckcmd() { - command -v sh >/dev/null 2>&1 && command -v $1 >/dev/null 2>&1 || type $1 >/dev/null 2>&1 +checkrestart() { + echo "-----------------------------------------------" + echo -e "\033[32m检测到已变更的内容,请重启服务!\033[0m" + echo "-----------------------------------------------" + read -p "是否现在重启服务?(1/0) > " res + [ "$res" = 1 ] && start_service +} +checkport() { #自动检查端口冲突 + for portx in $dns_port $mix_port $redir_port $((redir_port + 1)) $db_port; do + if [ -n "$(netstat -ntul 2>&1 | grep ':$portx ')" ]; then + echo "-----------------------------------------------" + echo -e "检测到端口【$portx】被以下进程占用!内核可能无法正常启动!\033[33m" + echo $(netstat -ntul | grep :$portx | head -n 1) + echo -e "\033[0m-----------------------------------------------" + echo -e "\033[36m请修改默认端口配置!\033[0m" + setport + . "$CFG_PATH" >/dev/null + checkport + fi + done } - #脚本启动前检查 ckstatus() { #检查/读取脚本配置文件 - if [ -f $CFG_PATH ]; then - [ -n "$(awk 'a[$0]++' $CFG_PATH)" ] && awk '!a[$0]++' $CFG_PATH >$CFG_PATH #检查重复行并去除 - . $CFG_PATH 2>/dev/null + if [ -f "$CFG_PATH" ]; then + [ -n "$(awk 'a[$0]++' $CFG_PATH)" ] && awk '!a[$0]++' "$CFG_PATH" >"$CFG_PATH" #检查重复行并去除 + . "$CFG_PATH" 2>/dev/null else - . ${CRASHDIR}/init.sh >/dev/null 2>&1 + . "$CRASHDIR"/init.sh >/dev/null 2>&1 fi - versionsh=$(cat ${CRASHDIR}/init.sh | grep -E ^version= | head -n 1 | sed 's/version=//') + versionsh=$(cat "$CRASHDIR"/init.sh | grep -E ^version= | head -n 1 | sed 's/version=//') [ -n "$versionsh" ] && versionsh_l=$versionsh #服务器缺省地址 [ -z "$mix_port" ] && mix_port=7890 @@ -48,7 +62,7 @@ ckstatus() { [ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' [ -z "$redir_mod" ] && redir_mod=纯净模式 #检查mac地址记录 - [ ! -f ${CRASHDIR}/configs/mac ] && touch ${CRASHDIR}/configs/mac + [ ! -f "$CRASHDIR"/configs/mac ] && touch "$CRASHDIR"/configs/mac #获取本机host地址 [ -z "$host" ] && host=$(ubus call network.interface.lan status 2>&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') [ -z "$host" ] && host=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'lan' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/\/[0-9][0-9].*$//g' | head -n 1) @@ -59,7 +73,7 @@ ckstatus() { dbdir=/www/clash hostdir=/clash else - dbdir=${CRASHDIR}/ui + dbdir="$CRASHDIR"/ui hostdir=":$db_port/ui" fi #开机自启检测 @@ -72,7 +86,7 @@ ckstatus() { elif rc-status -r >/dev/null 2>&1; then rc-update show default | grep -q "shellcrash" && autostart=enable || autostart=disable else - [ -f ${CRASHDIR}/.dis_startup ] && autostart=disable || autostart=enable + [ -f "$CRASHDIR"/.dis_startup ] && autostart=disable || autostart=enable fi #开机自启描述 if [ "$autostart" = "enable" ]; then @@ -88,8 +102,8 @@ ckstatus() { run="\033[32m正在运行($redir_mod)\033[0m" VmRSS=$(cat /proc/$PID/status | grep -w VmRSS | awk 'unit="MB" {printf "%.2f %s\n", $2/1000, unit}') #获取运行时长 - touch ${TMPDIR}/crash_start_time #用于延迟启动的校验 - start_time=$(cat ${TMPDIR}/crash_start_time) + touch "$TMPDIR"/crash_start_time #用于延迟启动的校验 + start_time=$(cat "$TMPDIR"/crash_start_time) if [ -n "$start_time" ]; then time=$(($(date +%s) - start_time)) day=$((time / 86400)) @@ -105,7 +119,7 @@ ckstatus() { fi corename=$(echo $crashcore | sed 's/singboxr/SingBoxR/' | sed 's/singbox/SingBox/' | sed 's/clash/Clash/' | sed 's/meta/Mihomo/') [ "$firewall_area" = 5 ] && corename='转发' - [ -f ${TMPDIR}/debug.log -o -f ${CRASHDIR}/debug.log -a -n "$PID" ] && auto="\033[33m并处于debug状态!\033[0m" + [ -f "$TMPDIR"/debug.log -o -f "$CRASHDIR"/debug.log -a -n "$PID" ] && auto="\033[33m并处于debug状态!\033[0m" #输出状态 echo "-----------------------------------------------" echo -e "\033[30;46m欢迎使用ShellCrash!\033[0m 版本:$versionsh_l" @@ -118,23 +132,23 @@ ckstatus() { #检查新手引导 if [ -z "$userguide" ]; then setconfig userguide 1 - . ${CRASHDIR}/webget.sh && userguide + . "$CRASHDIR"/webget.sh && userguide fi #检查执行权限 - [ ! -x ${CRASHDIR}/start.sh ] && chmod +x ${CRASHDIR}/start.sh + [ ! -x "$CRASHDIR"/start.sh ] && chmod +x "$CRASHDIR"/start.sh #检查/tmp内核文件 for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(gz|zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do chmod +x /tmp/$file echo -e "发现可用的内核文件: \033[36m/tmp/$file\033[0m " read -p "是否加载(会停止当前服务)?(1/0) > " res [ "$res" = 1 ] && { - ${CRASHDIR}/start.sh stop + "$CRASHDIR"/start.sh stop core_v=$(/tmp/$file -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') [ -z "$core_v" ] && core_v=$(/tmp/$file version 2>/dev/null | grep -Eo 'version .*' | sed 's/version //') if [ -n "$core_v" ]; then - . ${CRASHDIR}/webget.sh && setcoretype && - mv -f /tmp/$file ${TMPDIR}/CrashCore && - tar -zcf ${BINDIR}/CrashCore.tar.gz ${tar_para} -C ${TMPDIR} CrashCore && + . "$CRASHDIR"/webget.sh && setcoretype && + mv -f /tmp/$file "$TMPDIR"/CrashCore && + tar -zcf "$BINDIR"/CrashCore.tar.gz ${tar_para} -C "$TMPDIR" CrashCore && echo -e "\033[32m内核加载完成!\033[0m " && setconfig crashcore $crashcore && setconfig core_v $core_v && @@ -156,9 +170,9 @@ ckstatus() { read -p "是否加载为$crashcore的配置文件?(1/0) > " res [ "$res" = 1 ] && { if [ -n "$(echo /tmp/$file | grep -iE '.json$')" ]; then - mv -f /tmp/$file ${CRASHDIR}/jsons/config.json + mv -f /tmp/$file "$CRASHDIR"/jsons/config.json else - mv -f /tmp/$file ${CRASHDIR}/yamls/config.yaml + mv -f /tmp/$file "$CRASHDIR"/yamls/config.yaml fi echo -e "\033[32m配置文件加载完成!\033[0m " sleep 1 @@ -172,11 +186,7 @@ ckstatus() { echo "-----------------------------------------------" } } - -errornum() { - echo "-----------------------------------------------" - echo -e "\033[31m请输入正确的字母或数字!\033[0m" -} +#启动相关 startover() { echo -ne " \r" echo -e "\033[32m服务已启动!\033[0m" @@ -190,18 +200,18 @@ startover() { } start_core() { if echo "$crashcore" | grep -q 'singbox'; then - core_config=${CRASHDIR}/jsons/config.json + core_config="$CRASHDIR"/jsons/config.json else - core_config=${CRASHDIR}/yamls/config.yaml + core_config="$CRASHDIR"/yamls/config.yaml fi echo "-----------------------------------------------" - if [ ! -s $core_config -a -s $CRASHDIR/configs/providers.cfg ]; then + if [ ! -s $core_config -a -s "$CRASHDIR"/configs/providers.cfg ]; then echo -e "\033[33m没有找到${crashcore}配置文件,尝试生成providers配置文件!\033[0m" [ "$crashcore" = singboxr ] && coretype=singbox [ "$crashcore" = meta -o "$crashcore" = clashpre ] && coretype=clash - . ${CRASHDIR}/webget.sh && gen_${coretype}_providers + . "$CRASHDIR"/webget.sh && gen_${coretype}_providers elif [ -s $core_config -o -n "$Url" -o -n "$Https" ]; then - ${CRASHDIR}/start.sh start + "$CRASHDIR"/start.sh start #设置循环检测以判定服务启动是否成功 i=1 while [ -z "$test" -a "$i" -lt 30 ]; do @@ -216,1753 +226,40 @@ start_core() { [ -n "$test" -o -n "$(pidof CrashCore)" ] && startover else echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m" - . ${CRASHDIR}/webget.sh && set_core_config + . "$CRASHDIR"/webget.sh && set_core_config fi } start_service() { if [ "$firewall_area" = 5 ]; then - ${CRASHDIR}/start.sh start + "$CRASHDIR"/start.sh start echo -e "\033[32m已完成防火墙设置!\033[0m" else start_core fi } -checkrestart() { - echo "-----------------------------------------------" - echo -e "\033[32m检测到已变更的内容,请重启服务!\033[0m" - echo "-----------------------------------------------" - read -p "是否现在重启服务?(1/0) > " res - [ "$res" = 1 ] && start_service -} -#功能相关 -log_pusher() { #日志菜单 - [ -n "$push_TG" ] && stat_TG=32m已启用 || stat_TG=33m未启用 - [ -n "$push_Deer" ] && stat_Deer=32m已启用 || stat_Deer=33m未启用 - [ -n "$push_bark" ] && stat_bark=32m已启用 || stat_bark=33m未启用 - [ -n "$push_Po" ] && stat_Po=32m已启用 || stat_Po=33m未启用 - [ -n "$push_PP" ] && stat_PP=32m已启用 || stat_PP=33m未启用 - [ -n "$push_SynoChat" ] && stat_SynoChat=32m已启用 || stat_SynoChat=33m未启用 - [ -n "$push_Gotify" ] && stat_Gotify=32m已启用 || stat_Gotify=33m未启用 - [ "$task_push" = 1 ] && stat_task=32m已启用 || stat_task=33m未启用 - [ -n "$device_name" ] && device_s=32m$device_name || device_s=33m未设置 - echo "-----------------------------------------------" - echo -e " 1 Telegram推送 ——\033[$stat_TG\033[0m" - echo -e " 2 PushDeer推送 ——\033[$stat_Deer\033[0m" - echo -e " 3 Bark推送-IOS ——\033[$stat_bark\033[0m" - echo -e " 4 Passover推送 ——\033[$stat_Po\033[0m" - echo -e " 5 PushPlus推送 ——\033[$stat_PP\033[0m" - echo -e " 6 SynoChat推送 ——\033[$stat_SynoChat\033[0m" - echo -e " 7 Gotify推送 ——\033[$stat_Gotify\033[0m" - echo "-----------------------------------------------" - echo -e " a 查看\033[36m运行日志\033[0m" - echo -e " b 推送任务日志 ——\033[$stat_task\033[0m" - echo -e " c 设置设备名称 ——\033[$device_s\033[0m" - echo -e " d 清空日志文件" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - a) - if [ -s ${TMPDIR}/ShellCrash.log ]; then - echo "-----------------------------------------------" - cat ${TMPDIR}/ShellCrash.log - exit 0 - else - echo -e "\033[31m未找到相关日志!\033[0m" - fi - sleep 1 - ;; - 1) - echo "-----------------------------------------------" - if [ -n "$push_TG" ]; then - read -p "确认关闭TG日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_TG= - chat_ID= - setconfig push_TG - setconfig chat_ID - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - private_bot() { - echo -e "请先通过 \033[32;4mhttps://t.me/BotFather\033[0m 申请TG机器人并获取其\033[36mAPI TOKEN\033[0m" - echo "-----------------------------------------------" - read -p "请输入你获取到的API TOKEN > " TOKEN - echo "-----------------------------------------------" - echo -e "请向\033[32m你申请的机器人\033[33m而不是BotFather!\033[0m" - url_tg=https://api.telegram.org/bot${TOKEN}/getUpdates - } - public_bot() { - echo -e "请向机器人:\033[32;4mhttps://t.me/ShellCrashtg_bot\033[0m" - TOKEN=publictoken - url_tg=https://tgbot.jwsc.eu.org/publictoken/getUpdates - } - set_bot() { - echo -e "发送此秘钥: \033[30;46m$public_key\033[0m" - echo "-----------------------------------------------" - read -p "我已经发送完成(1/0) > " res - if [ "$res" = 1 ]; then - [ -n "$authentication" ] && auth="$authentication@" - export https_proxy="http://${auth}127.0.0.1:$mix_port" - if curl --version >/dev/null 2>&1; then - chat=$(curl -kfsSl $url_tg 2>/dev/null) - else - chat=$(wget -Y on -q -O - $url_tg) - fi - [ -n "$chat" ] && chat_ID=$(echo $chat | sed 's/"update_id":/{\n"update_id":/g' | grep "$public_key" | head -n1 | grep -oE '"id":.*,"is_bot' | sed s'/"id"://' | sed s'/,"is_bot//') - [ -z "$chat_ID" ] && { - echo -e "\033[31m无法获取对话ID,请返回重新设置或手动输入ChatID!\033[0m" - echo -e "通常访问 \033[32;4m$url_tg\033[0m \n\033[36m即可看到ChatID\033[0m" - read -p "请手动输入ChatID > " chat_ID - } - if echo "$chat_ID" | grep -qE '^[0-9]{8,}$'; then - push_TG=$TOKEN - setconfig push_TG $TOKEN - setconfig chat_ID $chat_ID - ${CRASHDIR}/start.sh logger "已完成Telegram日志推送设置!" 32 - else - echo -e "\033[31m无法获取对话ID,请重新配置!\033[0m" - sleep 1 - chose_bot - fi - fi - } - chose_bot() { - public_key=$(cat /proc/sys/kernel/random/boot_id | sed 's/.*-//') - echo "-----------------------------------------------" - echo -e " 1 使用公共机器人 ——不依赖内核服务" - echo -e " 2 使用私人机器人 ——需要额外申请" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case $num in - 1) - public_bot - set_bot - ;; - 2) - private_bot - set_bot - ;; - *) - errornum - ;; - esac - } - chose_bot - fi - sleep 1 - log_pusher - ;; - 2) - echo "-----------------------------------------------" - if [ -n "$push_Deer" ]; then - read -p "确认关闭PushDeer日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Deer= - setconfig push_Deer - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先前往 \033[32;4mhttp://www.pushdeer.com/official.html\033[0m 扫码安装快应用或下载APP" - echo -e "打开快应用/APP,并完成登陆" - echo -e "\033[33m切换到「设备」标签页,点击右上角的加号,注册当前设备\033[0m" - echo -e "\033[36m切换到「秘钥」标签页,点击右上角的加号,创建一个秘钥,并复制\033[0m" - echo "-----------------------------------------------" - read -p "请输入你复制的秘钥 > " url - if [ -n "$url" ]; then - push_Deer=$url - setconfig push_Deer $url - ${CRASHDIR}/start.sh logger "已完成PushDeer日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - sleep 1 - fi - log_pusher - ;; - 3) - echo "-----------------------------------------------" - if [ -n "$push_bark" ]; then - read -p "确认关闭Bark日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_bark= - bark_param= - setconfig push_bark - setconfig bark_param - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "\033[33mBark推送仅支持IOS系统,其他平台请使用其他推送方式!\033[0m" - echo -e "\033[32m请安装Bark-IOS客户端,并在客户端中找到专属推送链接\033[0m" - echo "-----------------------------------------------" - read -p "请输入你的Bark推送链接 > " url - if [ -n "$url" ]; then - push_bark=$url - setconfig push_bark $url - ${CRASHDIR}/start.sh logger "已完成Bark日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - sleep 1 - fi - log_pusher - ;; - 4) - echo "-----------------------------------------------" - if [ -n "$push_Po" ]; then - read -p "确认关闭Pushover日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Po= - push_Po_key= - setconfig push_Po - setconfig push_Po_key - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先通过 \033[32;4mhttps://pushover.net/\033[0m 注册账号并获取\033[36mUser Key\033[0m" - echo "-----------------------------------------------" - read -p "请输入你的User Key > " key - if [ -n "$key" ]; then - echo "-----------------------------------------------" - echo -e "\033[33m请检查注册邮箱,完成账户验证\033[0m" - read -p "我已经验证完成(1/0) > " - echo "-----------------------------------------------" - echo -e "请通过 \033[32;4mhttps://pushover.net/apps/build\033[0m 生成\033[36mAPI Token\033[0m" - echo "-----------------------------------------------" - read -p "请输入你的API Token > " Token - if [ -n "$Token" ]; then - push_Po=$Token - push_Po_key=$key - setconfig push_Po $Token - setconfig push_Po_key $key - ${CRASHDIR}/start.sh logger "已完成Passover日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - 5) - echo "-----------------------------------------------" - if [ -n "$push_PP" ]; then - read -p "确认关闭PushPlus日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_PP= - setconfig push_PP - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先通过 \033[32;4mhttps://www.pushplus.plus/push1.html\033[0m 注册账号并获取\033[36mtoken\033[0m" - echo "-----------------------------------------------" - read -p "请输入你的token > " Token - if [ -n "$Token" ]; then - push_PP=$Token - setconfig push_PP $Token - ${CRASHDIR}/start.sh logger "已完成PushPlus日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - 6) - echo "-----------------------------------------------" - if [ -n "$push_SynoChat" ]; then - read -p "确认关闭SynoChat日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_SynoChat= - setconfig push_SynoChat - } - else - echo "-----------------------------------------------" - read -p "请输入你的Synology DSM主页地址 > " URL - echo "-----------------------------------------------" - read -p "请输入你的Synology Chat Token > " TOKEN - echo "-----------------------------------------------" - echo -e '请通过"你的群晖地址/webapi/entry.cgi?api=SYNO.Chat.External&method=user_list&version=2&token=你的TOKEN"获取user_id' - echo "-----------------------------------------------" - read -p "请输入你的user_id > " USERID - if [ -n "$URL" ]; then - push_SynoChat=$USERID - setconfig push_SynoChat $USERID - setconfig push_ChatURL $URL - setconfig push_ChatTOKEN $TOKEN - setconfig push_ChatUSERID $USERID - ${CRASHDIR}/start.sh logger "已完成SynoChat日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - setconfig push_ChatURL - setconfig push_ChatTOKEN - setconfig push_ChatUSERID - push_SynoChat= - setconfig push_SynoChat - fi - fi - sleep 1 - log_pusher - ;; - # 在menu.sh的case $num in代码块中添加 - 7) - echo "-----------------------------------------------" - if [ -n "$push_Gotify" ]; then - read -p "确认关闭Gotify日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Gotify= - setconfig push_Gotify - } - else - echo -e "请先通过Gotify服务器获取推送URL" - echo -e "格式示例: https://gotify.example.com/message?token=你的应用令牌" - echo "-----------------------------------------------" - read -p "请输入你的Gotify推送URL > " url - if [ -n "$url" ]; then - push_Gotify=$url - setconfig push_Gotify "$url" - ${CRASHDIR}/start.sh logger "已完成Gotify日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - b) - [ "$task_push" = 1 ] && task_push='' || task_push=1 - setconfig task_push $task_push - sleep 1 - log_pusher - ;; - c) - read -p "请输入本设备自定义推送名称 > " device_name - setconfig device_name $device_name - sleep 1 - log_pusher - ;; - d) - echo -e "\033[33m运行日志及任务日志均已清空!\033[0m" - rm -rf ${TMPDIR}/ShellCrash.log - sleep 1 - log_pusher - ;; - *) errornum ;; - esac -} -setport() { #端口设置 - . $CFG_PATH >/dev/null - [ -z "$secret" ] && secret=未设置 - [ -z "$table" ] && table=100 - [ -z "$authentication" ] && auth=未设置 || auth=****** - inputport() { - read -p "请输入端口号(1-65535) > " portx - if [ -z "$portx" ]; then - setport - elif [ $portx -gt 65535 -o $portx -le 1 ]; then - echo -e "\033[31m输入错误!请输入正确的数值(1-65535)!\033[0m" - inputport - elif [ -n "$(echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep "|$portx|")" ]; then - echo -e "\033[31m输入错误!请不要输入重复的端口!\033[0m" - inputport - elif [ -n "$(netstat -ntul | grep ":$portx ")" ]; then - echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" - inputport - else - setconfig $xport $portx - echo -e "\033[32m设置成功!!!\033[0m" - setport - fi - } - echo "-----------------------------------------------" - echo -e " 1 修改Http/Sock5端口: \033[36m$mix_port\033[0m" - echo -e " 2 设置Http/Sock5密码: \033[36m$auth\033[0m" - echo -e " 3 修改Redir/Tproxy端口:\033[36m$redir_port,$((redir_port + 1))\033[0m" - echo -e " 4 修改DNS监听端口: \033[36m$dns_port\033[0m" - echo -e " 5 修改面板访问端口: \033[36m$db_port\033[0m" - echo -e " 6 设置面板访问密码: \033[36m$secret\033[0m" - echo -e " 7 修改默认端口过滤: \033[36m$multiport\033[0m" - echo -e " 8 自定义本机host地址: \033[36m$host\033[0m" - echo -e " 9 自定义路由表: \033[36m$table,$((table + 1))\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - xport=mix_port - inputport - ;; - 2) - echo "-----------------------------------------------" - echo -e "格式必须是\033[32m 用户名:密码 \033[0m的形式,注意用小写冒号分隔!" - echo -e "请尽量不要使用特殊符号!避免产生未知错误!" - echo "输入 0 删除密码" - echo "-----------------------------------------------" - read -p "请输入Http/Sock5用户名及密码 > " input - if [ "$input" = "0" ]; then - authentication="" - setconfig authentication - echo 密码已移除! - else - if [ "$local_proxy" = "已开启" -a "$local_type" = "环境变量" ]; then - echo "-----------------------------------------------" - echo -e "\033[33m请先禁用本机代理功能或使用增强模式!\033[0m" - sleep 1 - else - authentication=$(echo $input | grep :) - if [ -n "$authentication" ]; then - setconfig authentication "'$authentication'" - echo -e "\033[32m设置成功!!!\033[0m" - else - echo -e "\033[31m输入有误,请重新输入!\033[0m" - fi - fi - fi - setport - ;; - 3) - xport=redir_port - inputport - ;; - 4) - xport=dns_port - inputport - ;; - 5) - xport=db_port - inputport - ;; - 6) - read -p "请输入面板访问密码(输入0删除密码) > " secret - if [ -n "$secret" ]; then - [ "$secret" = "0" ] && secret="" - setconfig secret $secret - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - 7) - echo "-----------------------------------------------" - echo -e "需配合\033[32m仅代理常用端口\033[0m功能使用" - echo -e "多个端口请用小写逗号分隔,例如:\033[33m143,80,443\033[0m" - echo -e "输入 0 重置为默认端口" - echo "-----------------------------------------------" - read -p "请输入需要指定代理的端口 > " multiport - if [ -n "$multiport" ]; then - [ "$multiport" = "0" ] && multiport="22,80,143,194,443,465,587,853,993,995,5222,8080,8443" - common_ports=已开启 - setconfig multiport $multiport - setconfig common_ports $common_ports - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - 8) - echo "-----------------------------------------------" - echo -e "\033[33m如果你的局域网网段不是192.168.x或172.16.x或10.x开头,请务必修改!\033[0m" - echo -e "\033[31m设置后如本机host地址有变动,请务必重新修改!\033[0m" - echo "-----------------------------------------------" - read -p "请输入自定义host地址(输入0移除自定义host) > " host - if [ "$host" = "0" ]; then - host="" - setconfig host $host - echo -e "\033[32m已经移除自定义host地址,请重新运行脚本以自动获取host!!!\033[0m" - exit 0 - elif [ -n "$(echo $host | grep -E -o '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>){2}\.\<([1-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>')" ]; then - setconfig host $host - echo -e "\033[32m设置成功!!!\033[0m" - else - host="" - echo -e "\033[31m输入错误,请仔细核对!!!\033[0m" - fi - sleep 1 - setport - ;; - 9) - echo "-----------------------------------------------" - echo -e "\033[33m仅限Tproxy、Tun或混合模式路由表出现冲突时才需要设置!\033[0m" - read -p "请输入路由表地址(不明勿动!建议102-125之间) > " table - if [ -n "$table" ]; then - [ "$table" = "0" ] && table="100" - setconfig table $table - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - *) - errornum - ;; - esac -} -setdns() { #DNS详细设置 - [ -z "$dns_nameserver" ] && dns_nameserver='223.5.5.5, 1.2.4.8' - [ -z "$dns_fallback" ] && dns_fallback="1.1.1.1, 8.8.8.8" - [ -z "$dns_resolver" ] && dns_resolver="223.5.5.5, 2400:3200::1" - [ -z "$hosts_opt" ] && hosts_opt=已启用 - [ -z "$dns_protect" ] && dns_protect=ON - [ -z "$dns_redir" ] && dns_redir=未开启 - [ -z "$dns_no" ] && dns_no=未禁用 - echo "-----------------------------------------------" - echo -e "当前基础DNS:\033[32m$dns_nameserver\033[0m" - echo -e "PROXY-DNS:\033[36m$dns_fallback\033[0m" - echo -e "解析DNS:\033[33m$dns_resolver\033[0m" - echo -e "多个DNS地址请用\033[30;47m“|”\033[0m或者\033[30;47m“, ”\033[0m分隔输入" - echo -e "\033[33m必须拥有本地根证书文件才能使用dot/doh类型的加密dns\033[0m" - echo -e "\033[31m注意singbox内核只有首个dns会被加载!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 修改\033[32m基础DNS\033[0m" - echo -e " 2 修改\033[36mPROXY-DNS\033[0m(该DNS查询会经过节点)" - echo -e " 3 修改\033[33m解析DNS\033[0m(必须是IP,用于解析其他DNS)" - echo -e " 4 DNS防泄漏: \033[36m$dns_protect\033[0m ———启用时少量网站可能连接卡顿" - echo -e " 5 hosts优化: \033[36m$hosts_opt\033[0m ———调用本机hosts并劫持NTP服务" - #echo -e " 6 Dnsmasq转发:\033[36m$dns_redir\033[0m ———不推荐使用" - echo -e " 7 禁用DNS劫持:\033[36m$dns_no\033[0m ———搭配第三方DNS使用" - echo -e " 8 一键配置\033[32m加密DNS\033[0m" - echo -e " 9 \033[33m重置\033[0m默认DNS配置" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - read -p "请输入新的DNS > " dns_nameserver - dns_nameserver=$(echo $dns_nameserver | sed 's#|#\,\ #g') - if [ -n "$dns_nameserver" ]; then - setconfig dns_nameserver "'$dns_nameserver'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 2) - read -p "请输入新的DNS > " dns_fallback - dns_fallback=$(echo $dns_fallback | sed 's/|/\,\ /g') - if [ -n "$dns_fallback" ]; then - setconfig dns_fallback "'$dns_fallback'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 3) - read -p "请输入新的DNS > " text - if echo "$text" | grep -qE '://.*::'; then - echo -e "\033[31m此选项暂不支持ipv6加密DNS!!!\033[0m" - elif [ -n "$text" ]; then - dns_resolver=$(echo $text | sed 's/|/\,\ /g') - setconfig dns_resolver "'$dns_resolver'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 4) - [ "$dns_protect" = "ON" ] && dns_protect=OFF || dns_protect=ON - setconfig dns_protect $dns_protect - setdns - ;; - 5) - echo "-----------------------------------------------" - if [ "$hosts_opt" = "已启用" ]; then - hosts_opt=未启用 - echo -e "\033[32m已禁用hosts优化功能!!!\033[0m" - else - hosts_opt=已启用 - echo -e "\033[33m已启用hosts优化功能!!!\033[0m" - fi - setconfig hosts_opt $hosts_opt - sleep 1 - setdns - ;; - 6) - echo "-----------------------------------------------" - if [ "$dns_redir" = "未开启" ]; then - echo -e "\033[31m将使用OpenWrt中Dnsmasq插件自带的DNS转发功能转发DNS请求至内核!\033[0m" - echo -e "\033[33m启用后将禁用本插件自带的iptables转发功能\033[0m" - dns_redir=已开启 - echo -e "\033[32m已启用Dnsmasq转发DNS功能!!!\033[0m" - else - uci del dhcp.@dnsmasq[-1].server - uci set dhcp.@dnsmasq[0].noresolv=0 - uci commit dhcp - /etc/init.d/dnsmasq restart - echo -e "\033[33m禁用成功!!如有报错请重启设备!\033[0m" - dns_redir=未开启 - fi - setconfig dns_redir $dns_redir - sleep 1 - setdns - ;; - 7) - echo "-----------------------------------------------" - if [ "$dns_no" = "未禁用" ]; then - echo -e "\033[31m仅限搭配其他DNS服务(比如dnsmasq、smartDNS)时使用!\033[0m" - dns_no=已禁用 - echo -e "\033[32m已禁用DNS劫持!!!\033[0m" - else - dns_no=未禁用 - echo -e "\033[33m已启用DNS劫持!!!\033[0m" - fi - setconfig dns_no $dns_no - sleep 1 - setdns - ;; - 8) - echo "-----------------------------------------------" - openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" - if [ -s "$openssldir/certs/ca-certificates.crt" ] || [ -s "/etc/ssl/certs/ca-certificates.crt" ] || - echo "$crashcore" | grep -qE 'meta|singbox'; then - dns_nameserver='https://dns.alidns.com/dns-query, https://doh.pub/dns-query' - dns_fallback='https://cloudflare-dns.com/dns-query, https://dns.google/dns-query, https://doh.opendns.com/dns-query' - dns_resolver='https://223.5.5.5/dns-query, 2400:3200::1' - setconfig dns_nameserver "'$dns_nameserver'" - setconfig dns_fallback "'$dns_fallback'" - setconfig dns_resolver "'$dns_resolver'" - echo -e "\033[32m已设置加密DNS,如出现DNS解析问题,请尝试重置DNS配置!\033[0m" - else - echo -e "\033[31m找不到根证书文件,无法启用加密DNS,Linux系统请自行搜索安装OpenSSL的方式!\033[0m" - fi - sleep 1 - setdns - ;; - 9) - dns_nameserver= - dns_fallback= - dns_resolver= - setconfig dns_nameserver - setconfig dns_fallback - setconfig dns_resolver - echo -e "\033[33mDNS配置已重置!!!\033[0m" - sleep 1 - setdns - ;; - *) - errornum - sleep 1 - ;; - esac -} -setipv6() { #ipv6设置 - [ -z "$ipv6_redir" ] && ipv6_redir=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 - echo "-----------------------------------------------" - echo -e " 1 ipv6透明代理: \033[36m$ipv6_redir\033[0m ——代理ipv6流量" - [ "$disoverride" != "1" ] && echo -e " 2 ipv6-DNS解析: \033[36m$ipv6_dns\033[0m ——决定内置DNS是否返回ipv6地址" - echo -e " 3 CNV6绕过内核: \033[36m$cn_ipv6_route\033[0m ——优化性能,不兼容fake-ip" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - if [ "$ipv6_redir" = "未开启" ]; then - ipv6_support=已开启 - ipv6_redir=已开启 - sleep 2 - else - ipv6_redir=未开启 - fi - setconfig ipv6_redir $ipv6_redir - setconfig ipv6_support $ipv6_support - setipv6 - ;; - 2) - [ "$ipv6_dns" = "未开启" ] && ipv6_dns=已开启 || ipv6_dns=未开启 - setconfig ipv6_dns $ipv6_dns - setipv6 - ;; - 3) - if [ "$ipv6_redir" = "未开启" ]; then - ipv6_support=已开启 - ipv6_redir=已开启 - setconfig ipv6_redir $ipv6_redir - setconfig ipv6_support $ipv6_support - fi - if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = nftables ]; then - [ "$cn_ipv6_route" = "未开启" ] && cn_ipv6_route=已开启 || cn_ipv6_route=未开启 - setconfig cn_ipv6_route $cn_ipv6_route - else - echo -e "\033[31m当前设备缺少ipset模块或防火墙未使用nftables,无法启用绕过功能!!\033[0m" - sleep 1 - fi - setipv6 - ;; - *) - errornum - ;; - esac -} -setfirewall() { #防火墙设置 - - [ -z "$public_support" ] && public_support=未开启 - [ -z "$public_mixport" ] && public_mixport=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 - echo "-----------------------------------------------" - echo -e " 1 公网访问Dashboard面板: \033[36m$public_support\033[0m" - echo -e " 2 公网访问Socks/Http代理: \033[36m$public_mixport\033[0m" - echo -e " 3 自定义透明路由ipv4网段: 适合vlan等复杂网络环境" - echo -e " 4 自定义保留地址ipv4网段: 需要以保留地址为访问目标的环境" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 1) - if [ "$public_support" = "未开启" ]; then - public_support=已开启 - else - public_support=未开启 - fi - setconfig public_support $public_support - setfirewall - ;; - 2) - if [ "$public_mixport" = "未开启" ]; then - if [ "$mix_port" = "7890" -o -z "$authentication" ]; then - echo "-----------------------------------------------" - echo -e "\033[33m为了安全考虑,请先修改默认Socks/Http端口并设置代理密码\033[0m" - sleep 1 - setport - else - public_mixport=已开启 - fi - else - public_mixport=未开启 - fi - setconfig public_mixport $public_mixport - setfirewall - ;; - 3) - set_cust_host_ipv4 - setfirewall - ;; - 4) - [ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" - echo -e "当前网段:\033[36m$reserve_ipv4\033[0m" - echo -e "\033[33m地址必须是空格分隔,错误的设置可能导致网络回环或启动报错,请务必谨慎!\033[0m" - read -p "请输入 > " text - if [ -n "$( - echo $text | grep -E "(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[1-2]?[0-9]))( +|$)+" - )" ]; then - reserve_ipv4="$text" - echo -e "已将保留地址网段设为:\033[32m$reserve_ipv4\033[0m" - setconfig reserve_ipv4 "'$reserve_ipv4'" - else - echo -e "\033[31m输入有误,操作已取消!\033[0m" - fi - sleep 1 - setfirewall - ;; - *) - errornum - ;; - esac -} -checkport() { #自动检查端口冲突 - for portx in $dns_port $mix_port $redir_port $((redir_port + 1)) $db_port; do - if [ -n "$(netstat -ntul 2>&1 | grep ':$portx ')" ]; then - echo "-----------------------------------------------" - echo -e "检测到端口【$portx】被以下进程占用!内核可能无法正常启动!\033[33m" - echo $(netstat -ntul | grep :$portx | head -n 1) - echo -e "\033[0m-----------------------------------------------" - echo -e "\033[36m请修改默认端口配置!\033[0m" - setport - . $CFG_PATH >/dev/null - checkport - fi - done -} -macfilter() { #局域网设备过滤 - get_devinfo() { - dev_ip=$(cat $dhcpdir | grep " $dev " | awk '{print $3}') && [ -z "$dev_ip" ] && dev_ip=$dev - dev_mac=$(cat $dhcpdir | grep " $dev " | awk '{print $2}') && [ -z "$dev_mac" ] && dev_mac=$dev - dev_name=$(cat $dhcpdir | grep " $dev " | awk '{print $4}') && [ -z "$dev_name" ] && dev_name='未知设备' - } - add_mac() { - echo "-----------------------------------------------" - echo 已添加的mac地址: - cat ${CRASHDIR}/configs/mac 2>/dev/null - echo "-----------------------------------------------" - echo -e "\033[33m序号 设备IP 设备mac地址 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$2,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入mac地址时仅支持\033[32mxx:xx:xx:xx:xx:xx\033[0m的形式" - echo -e " 0 或回车 结束添加" - echo "-----------------------------------------------" - read -p "请输入对应序号或直接输入mac地址 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$num")" ]; then - echo $num | grep -oE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' >>${CRASHDIR}/configs/mac - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - macadd=$(cat $dhcpdir | awk '{print $2}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$macadd")" ]; then - echo $macadd >>${CRASHDIR}/configs/mac - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_mac - fi - } - add_ip() { - echo "-----------------------------------------------" - echo "已添加的IP地址(段):" - cat ${CRASHDIR}/configs/ip_filter 2>/dev/null - echo "-----------------------------------------------" - echo -e "\033[33m序号 设备IP 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入时仅支持\033[32m 192.168.1.0/24\033[0m 或 \033[32m192.168.1.0\033[0m 的形式" - echo -e "不支持ipv6地址过滤,如有需求请使用mac地址过滤" - echo -e " 0 或回车 结束添加" - echo "-----------------------------------------------" - read -p "请输入对应序号或直接输入IP地址段 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/ip_filter | grep -E "$num")" ]; then - echo $num | grep -oE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$' >>${CRASHDIR}/configs/ip_filter - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - ipadd=$(cat $dhcpdir | awk '{print $3}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$ipadd")" ]; then - echo $ipadd >>${CRASHDIR}/configs/ip_filter - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_ip - fi - } - del_all() { - echo "-----------------------------------------------" - if [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ]; then - echo -e "\033[31m列表中没有需要移除的设备!\033[0m" - sleep 1 - else - echo -e "请选择需要移除的设备:\033[36m" - echo -e "\033[33m 设备IP 设备mac地址 设备名称\033[0m" - i=1 - for dev in $(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e " $i \033[32m$dev_ip \033[36m$dev_mac \033[32m$dev_name\033[0m" - i=$((i + 1)) - done - echo "-----------------------------------------------" - echo -e "\033[0m 0 或回车 结束删除" - read -p "请输入需要移除的设备的对应序号 > " num - mac_filter_rows=$(cat ${CRASHDIR}/configs/mac 2>/dev/null | wc -l) - ip_filter_rows=$(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null | wc -l) - if [ -z "$num" ] || [ "$num" -le 0 ]; then - n= - elif [ $num -le $mac_filter_rows ]; then - sed -i "${num}d" ${CRASHDIR}/configs/mac - echo "-----------------------------------------------" - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - elif [ $num -le $((mac_filter_rows + ip_filter_rows)) ]; then - num=$((num - mac_filter_rows)) - sed -i "${num}d" ${CRASHDIR}/configs/ip_filter - echo "-----------------------------------------------" - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - del_all - fi - fi - } - echo "-----------------------------------------------" - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcp/dhcpd.leases ] && dhcpdir='/var/lib/dhcp/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcpd/dhcpd.leases ] && dhcpdir='/var/lib/dhcpd/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dhcp.leases ] && dhcpdir='/tmp/dhcp.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dnsmasq.leases ] && dhcpdir='/tmp/dnsmasq.leases' - [ -z "$dhcpdir" ] && dhcpdir='/dev/null' - [ -z "$macfilter_type" ] && macfilter_type='黑名单' - if [ "$macfilter_type" = "黑名单" ]; then - macfilter_over='白名单' - macfilter_scrip='不' - else - macfilter_over='黑名单' - macfilter_scrip='' - fi - ###### - echo -e "\033[30;47m请在此添加或移除设备\033[0m" - echo -e "当前过滤方式为:\033[33m$macfilter_type模式\033[0m" - echo -e "仅列表内设备流量\033[36m$macfilter_scrip经过\033[0m内核" - if [ -n "$(cat ${CRASHDIR}/configs/mac)" ]; then - echo "-----------------------------------------------" - echo -e "当前已过滤设备为:\033[36m" - echo -e "\033[33m 设备mac/ip地址 设备名称\033[0m" - for dev in $(cat ${CRASHDIR}/configs/mac 2>/dev/null); do - get_devinfo - echo -e "\033[36m$dev_mac \033[0m$dev_name" - done - for dev in $(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e "\033[32m$dev_ip \033[0m$dev_name" - done - echo "-----------------------------------------------" - fi - echo -e " 1 切换为\033[33m$macfilter_over模式\033[0m" - echo -e " 2 \033[32m添加指定设备(mac地址)\033[0m" - echo -e " 3 \033[32m添加指定设备(IP地址/网段)\033[0m" - echo -e " 4 \033[36m移除指定设备\033[0m" - echo -e " 9 \033[31m清空整个列表\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - macfilter_type=$macfilter_over - setconfig macfilter_type $macfilter_type - echo "-----------------------------------------------" - echo -e "\033[32m已切换为$macfilter_type模式!\033[0m" - macfilter - ;; - 2) - add_mac - macfilter - ;; - 3) - add_ip - macfilter - ;; - 4) - del_all - macfilter - ;; - 9) - : >${CRASHDIR}/configs/mac - : >${CRASHDIR}/configs/ip_filter - echo "-----------------------------------------------" - echo -e "\033[31m设备列表已清空!\033[0m" - macfilter - ;; - *) - errornum - ;; - esac -} -setboot() { #启动相关设置 - [ -z "$start_old" ] && start_old=未开启 - [ -z "$start_delay" -o "$start_delay" = 0 ] && delay=未设置 || delay=${start_delay}秒 - [ "$autostart" = "enable" ] && auto_set="\033[33m禁止" || auto_set="\033[32m允许" - [ "${BINDIR}" = "${CRASHDIR}" ] && mini_clash=未开启 || mini_clash=已开启 - [ -z "$network_check" ] && network_check=已开启 - echo "-----------------------------------------------" - echo -e "\033[30;47m欢迎使用启动设置菜单:\033[0m" - echo "-----------------------------------------------" - echo -e " 1 ${auto_set}\033[0mShellCrash开机启动" - echo -e " 2 使用保守模式: \033[36m$start_old\033[0m ————基于定时任务(每分钟检测)" - echo -e " 3 设置自启延时: \033[36m$delay\033[0m ————用于解决自启后服务受限" - echo -e " 4 启用小闪存模式: \033[36m$mini_clash\033[0m ————用于闪存空间不足的设备" - [ "${BINDIR}" != "${CRASHDIR}" ] && echo -e " 5 设置小闪存目录: \033[36m${BINDIR}\033[0m" - echo -e " 6 自启网络检查: \033[36m$network_check\033[0m ————禁用则跳过自启时网络检查" - echo "-----------------------------------------------" - echo -e " 0 \033[0m返回上级菜单\033[0m" - read -p "请输入对应数字 > " num - echo "-----------------------------------------------" - case "$num" in - 0) ;; - 1) - if [ "$autostart" = "enable" ]; then - # 禁止自启动:删除各系统的启动项 - [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null - ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 - grep -q 's6' /proc/1/comm && rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/afstart - rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null 2>&1 - touch ${CRASHDIR}/.dis_startup - autostart=disable - echo -e "\033[33m已禁止ShellCrash开机启动!\033[0m" - elif [ "$autostart" = "disable" ]; then - # 允许自启动:配置各系统的启动项 - [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ] && /etc/init.d/shellcrash enable - ckcmd systemctl && systemctl enable shellcrash.service >/dev/null 2>&1 - grep -q 's6' /proc/1/comm && touch /etc/s6-overlay/s6-rc.d/user/contents.d/afstart - rc-status -r >/dev/null 2>&1 && rc-update add shellcrash default >/dev/null 2>&1 - rm -rf ${CRASHDIR}/.dis_startup - autostart=enable - echo -e "\033[32m已设置ShellCrash开机启动!\033[0m" - fi - setboot - ;; - 2) - if [ "$start_old" = "未开启" ] >/dev/null 2>&1; then - echo -e "\033[33m改为使用保守模式启动服务!!\033[0m" - [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null - ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 - grep -q 's6' /proc/1/comm && rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/afstart - rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null 2>&1 - start_old=已开启 - setconfig start_old $start_old - ${CRASHDIR}/start.sh stop - else - if grep -qE 'procd|systemd|s6' /proc/1/comm || rc-status -r >/dev/null 2>&1; then - echo -e "\033[32m改为使用系统守护进程启动服务!!\033[0m" - ${CRASHDIR}/start.sh cronset "ShellCrash初始化" - start_old=未开启 - setconfig start_old $start_old - ${CRASHDIR}/start.sh stop - - else - echo -e "\033[31m当前设备不支持以其他模式启动!!\033[0m" - fi - fi - sleep 1 - setboot - ;; - 3) - echo -e "\033[33m如果你的设备启动后可以正常使用,则无需设置!!\033[0m" - echo -e "\033[36m推荐设置为30~120秒之间,请根据设备问题自行试验\033[0m" - read -p "请输入启动延迟时间(0~300秒) > " sec - case "$sec" in - [0-9] | [0-9][0-9] | [0-2][0-9][0-9] | 300) - start_delay=$sec - setconfig start_delay $sec - echo -e "\033[32m设置成功!\033[0m" - ;; - *) - echo -e "\033[31m输入有误,或超过300秒,请重新输入!\033[0m" - ;; - esac - sleep 1 - setboot - ;; - 4) - dir_size=$(df ${CRASHDIR} | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | grep Ava | awk '{print $2}') - if [ "$mini_clash" = "未开启" ]; then - if [ "$dir_size" -gt 20480 ]; then - echo -e "\033[33m您的设备空间充足(>20M),无需开启!\033[0m" - elif [ "$start_old" != '已开启' -a "$(cat /proc/1/comm)" = "systemd" ]; then - echo -e "\033[33m不支持systemd启动模式,请先启用保守模式!\033[0m" - else - [ "$BINDIR" = "$CRASHDIR" ] && BINDIR="$TMPDIR" - echo -e "\033[32m已经启用小闪存功能!\033[0m" - echo -e "如需更换目录,请使用【设置小闪存目录】功能\033[0m" - fi - else - if [ "$dir_size" -lt 8192 ]; then - echo -e "\033[31m您的设备剩余空间不足8M,停用后可能无法正常运行!\033[0m" - read -p "确认停用此功能?(1/0) > " res - [ "$res" = 1 ] && BINDIR="$CRASHDIR" && echo -e "\033[33m已经停用小闪存功能!\033[0m" - else - rm -rf /tmp/ShellCrash - BINDIR="$CRASHDIR" - echo -e "\033[33m已经停用小闪存功能!\033[0m" - fi - fi - setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env - sleep 1 - setboot - ;; - 5) - echo -e "\033[33m如设置到内存,则每次开机后都自动重新下载相关文件\033[0m" - echo -e "\033[33m请确保安装源可用裸连,否则会导致启动失败\033[0m" - echo " 1 使用内存(/tmp)" - echo " 2 选择U盘目录" - echo " 3 自定义目录" - read -p "请输入相应数字 > " num - case "$num" in - 1) - BINDIR="$TMPDIR" - ;; - 2) - set_usb_dir() { - echo "请选择安装目录" - du -hL /mnt | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - BINDIR=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) - if [ -z "$BINDIR" ]; then - echo "\033[31m输入错误!请重新设置!\033[0m" - set_usb_dir - fi - } - set_usb_dir - ;; - 3) - input_dir() { - read -p "请输入自定义目录 > " BINDIR - if [ ! -d "$BINDIR" ]; then - echo "\033[31m输入错误!请重新设置!\033[0m" - input_dir - fi - } - input_dir - ;; - *) - errornum - ;; - esac - setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env - setboot - ;; - 6) - echo -e "\033[33m如果你的设备启动后可以正常使用,则无需变更设置!!\033[0m" - echo -e "\033[36m禁用时,如果使用了小闪存模式或者rule-set等在线规则,则可能会因无法联网而导致启动失败!\033[0m" - echo -e "\033[32m启用时,会导致部分性能较差或者拨号较慢的设备可能会因查询超时导致启动失败!\033[0m" - read -p "是否切换?(1/0) > " res - [ "$res" = '1' ] && { - if [ "$network_check" = "已禁用" ]; then - network_check=已启用 - else - network_check=已禁用 - fi - setconfig network_check $network_check - } - sleep 1 - setboot - ;; - *) - errornum - ;; - esac - -} -set_firewall_area() { #防火墙模式设置 - [ -z "$vm_redir" ] && vm_redir='未开启' - echo "-----------------------------------------------" - echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6!" - echo -e "\033[33m如你使用了第三方DNS如smartdns等,请勿启用本机代理或使用shellcrash用户执行!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 \033[32m仅劫持局域网流量\033[0m" - echo -e " 2 \033[36m仅劫持本机流量\033[0m" - echo -e " 3 \033[32m劫持局域网+本机流量\033[0m" - echo -e " 4 不配置流量劫持(纯净模式)\033[0m" - #echo -e " 5 \033[33m转发局域网流量到旁路由设备\033[0m" - echo -e " 6 劫持容器/虚拟机流量: \033[36m$vm_redir\033[0m" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - [1-4]) - [ $firewall_area -ge 4 ] && { - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - } - [ "$num" = 4 ] && { - redir_mod=纯净模式 - setconfig redir_mod $redir_mod - } - firewall_area=$num - setconfig firewall_area $firewall_area - ;; - 5) - echo "-----------------------------------------------" - echo -e "\033[31m注意:\033[0m此功能存在多种风险如无网络基础请勿尝试!" - echo -e "\033[33m说明:\033[0m此功能不启动内核仅配置防火墙转发,且子设备无需额外设置网关DNS" - echo -e "\033[33m说明:\033[0m支持防火墙分流及设备过滤,支持部分定时任务,但不支持ipv6!" - echo -e "\033[31m注意:\033[0m如需代理UDP,请确保旁路由运行了支持UDP代理的模式!" - echo -e "\033[31m注意:\033[0m如使用systemd方式启动,内核依然会空载运行,建议使用保守模式!" - echo "-----------------------------------------------" - read -p "请输入旁路由IPV4地址 > " bypass_host - [ -n "$bypass_host" ] && { - firewall_area=$num - setconfig firewall_area $firewall_area - setconfig bypass_host $bypass_host - redir_mod=TCP旁路转发 - setconfig redir_mod $redir_mod - } - ;; - 6) - if [ -n "$vm_ipv4" ]; then - vm_des='当前劫持' - else - vm_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -E 'docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | sed 's/.*inet.//g' | sed 's/ br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ') - vm_des='当前获取到' - fi - echo "-----------------------------------------------" - echo -e "$vm_des的容器/虚拟机网段为:\033[32m$vm_ipv4\033[0m" - echo -e "如未包含容器网段,请先运行容器再运行脚本或者手动设置网段" - echo "-----------------------------------------------" - echo -e " 1 \033[32m启用劫持并使用默认网段\033[0m" - echo -e " 2 \033[36m启用劫持并自定义网段\033[0m" - echo -e " 3 \033[31m禁用劫持\033[0m" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 1) - if [ -n "$vm_ipv4" ]; then - vm_redir=已开启 - else - echo -e "\033[33m请先运行容器再运行脚本或者手动设置网段\033[0m" - fi - ;; - 2) - echo -e "多个网段请用空格连接,可运行容器后使用【ip route】命令查看网段地址" - echo -e "示例:\033[32m10.88.0.0/16 172.17.0.0/16\033[0m" - read -p "请输入自定义网段 > " text - [ -n "$text" ] && vm_ipv4=$text && vm_redir=已开启 - ;; - 3) - vm_redir=未开启 - unset vm_ipv4 - ;; - *) ;; - esac - setconfig vm_redir $vm_redir - setconfig vm_ipv4 "'$vm_ipv4'" - sleep 1 - set_firewall_area - ;; - *) errornum ;; - esac - sleep 1 -} -set_redir_mod() { #代理模式设置 - set_redir_config() { - setconfig redir_mod $redir_mod - setconfig dns_mod $dns_mod - echo "-----------------------------------------------" - echo -e "\033[36m已设为 $redir_mod !!\033[0m" - } - [ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1 - [ -z "$firewall_area" ] && firewall_area=1 - [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' - [ -z "$redir_mod" ] && redir_mod='纯净模式' - firewall_area_dsc=$(echo "仅局域网 仅本机 局域网+本机 纯净模式 主-旁转发($bypass_host)" | cut -d' ' -f$firewall_area) - echo "-----------------------------------------------" - echo -e "当前代理模式为:\033[47;30m$redir_mod\033[0m;ShellCrash核心为:\033[47;30m $crashcore \033[0m" - echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" - echo "-----------------------------------------------" - [ $firewall_area -le 3 ] && { - echo -e " 1 \033[32mRedir模式\033[0m: Redir转发TCP,不转发UDP" - echo -e " 2 \033[36m混合模式\033[0m: Redir转发TCP,Tun转发UDP" - echo -e " 3 \033[32mTproxy模式\033[0m: Tproxy转发TCP&UDP" - echo -e " 4 \033[33mTun模式\033[0m: Tun转发TCP&UDP(占用高不推荐)" - echo "-----------------------------------------------" - } - [ "$firewall_area" = 5 ] && { - echo -e " 5 \033[32mTCP旁路转发\033[0m: 仅转发TCP流量至旁路由" - echo -e " 6 \033[36mT&U旁路转发\033[0m: 转发TCP&UDP流量至旁路由" - echo "-----------------------------------------------" - } - echo -e " 7 设置劫持范围:\033[47;30m$firewall_area_dsc\033[0m" - echo -e " 8 切换防火墙应用:\033[47;30m$firewall_mod\033[0m" - echo -e " 9 ipv6设置:\033[47;30m$ipv6_redir\033[0m" - echo " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - redir_mod=Redir模式 - set_redir_config - set_redir_mod - ;; - 2) - if [ -n "$sup_tun" ]; then - redir_mod=混合模式 - set_redir_config - else - echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - set_redir_mod - ;; - 3) - if [ "$firewall_mod" = "iptables" ]; then - if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ]; then - read -p "xiaomi设备的QOS服务与本模式冲突,是否禁用相关功能?(1/0) > " res - [ "$res" = '1' ] && { - ${CRASHDIR}/misnap_init.sh tproxyfix - redir_mod=Tproxy模式 - set_redir_config - } - elif grep -qE '^TPROXY$' /proc/net/ip_tables_targets || modprobe xt_TPROXY >/dev/null 2>&1; then - redir_mod=Tproxy模式 - set_redir_config - else - echo -e "\033[31m设备未检测到iptables-mod-tproxy模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - elif [ "$firewall_mod" = "nftables" ]; then - if modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy; then - redir_mod=Tproxy模式 - set_redir_config - else - echo -e "\033[31m设备未检测到nft_tproxy内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - fi - set_redir_mod - ;; - 4) - if [ -n "$sup_tun" ]; then - redir_mod=Tun模式 - set_redir_config - else - echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - set_redir_mod - ;; - 5) - redir_mod=TCP旁路转发 - set_redir_config - set_redir_mod - ;; - 6) - redir_mod=T & - U旁路转发 - set_redir_config - set_redir_mod - ;; - 7) - set_firewall_area - set_redir_mod - ;; - 8) - if [ "$firewall_mod" = 'iptables' ]; then - if nft add table inet shellcrash 2>/dev/null; then - firewall_mod=nftables - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - else - echo -e "\033[31m当前设备未安装nftables或者nftables版本过低(<1.0.2),无法切换!\033[0m" - fi - elif [ "$firewall_mod" = 'nftables' ]; then - if ckcmd iptables; then - firewall_mod=iptables - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - else - echo -e "\033[31m当前设备未安装iptables,无法切换!\033[0m" - fi - else - iptables -j REDIRECT -h >/dev/null 2>&1 && firewall_mod=iptables - nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables - if [ -n "$firewall_mod" ]; then - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - setconfig firewall_mod $firewall_mod - else - echo -e "\033[31m检测不到可用的防火墙应用(iptables/nftables),无法切换!\033[0m" - fi - fi - sleep 1 - setconfig firewall_mod $firewall_mod - set_redir_mod - ;; - 9) - setipv6 - set_redir_mod - ;; - *) - errornum - ;; - esac -} -set_dns_mod() { #DNS模式设置 - echo "-----------------------------------------------" - echo -e "当前DNS运行模式为:\033[47;30m $dns_mod \033[0m" - echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 fake-ip模式: 响应快,\033[33m兼容性较差\033[0m" - echo -e " 不支持CN-IP绕过功能" - echo -e " 2 redir_host模式:\033[33m不安全,易被污染\033[0m" - echo -e " 建议搭配第三方DNS服务使用" - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - echo -e " 3 mix混合模式: \033[32m防污染防泄露,响应快,推荐!\033[0m" - echo -e " cn域名realip其他fakeip分流" - echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" - echo -e " cn域名realip其他dns2proxy分流" - fi - echo -e " 9 \033[36mDNS进阶设置\033[0m" - echo " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - dns_mod=fake-ip - setconfig dns_mod $dns_mod - echo "-----------------------------------------------" - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - ;; - 2) - dns_mod=redir_host - setconfig dns_mod $dns_mod - echo "-----------------------------------------------" - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - ;; - 3) - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - dns_mod=mix - setconfig dns_mod $dns_mod - echo "-----------------------------------------------" - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - else - echo -e "\033[31m当前内核不支持的功能!!!\033[0m" - sleep 1 - fi - ;; - 4) - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - dns_mod=route - setconfig dns_mod $dns_mod - echo "-----------------------------------------------" - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - else - echo -e "\033[31m当前内核不支持的功能!!!\033[0m" - sleep 1 - fi - ;; - 9) - setdns - set_dns_mod - ;; - *) - errornum - ;; - esac -} -fake_ip_filter() { - echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m" - echo -e "\033[31m脚本已经内置了大量地址,你只需要添加出现问题的地址!\033[0m" - echo -e "\033[36m示例:a.b.com" - echo -e "示例:*.b.com" - echo -e "示例:*.*.b.com\033[0m" - echo "-----------------------------------------------" - if [ -s ${CRASHDIR}/configs/fake_ip_filter ]; then - echo -e "\033[33m已添加Fake-ip过滤地址:\033[0m" - cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}' - else - echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m" - fi - echo "-----------------------------------------------" - echo -e "\033[32m输入数字直接移除对应地址,输入地址直接添加!\033[0m" - read -p "请输入数字或地址 > " input - case "$input" in - 0) ;; - '') ;; - *) - if [ $input -ge 1 ] 2>/dev/null; then - sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null - echo -e "\033[32m移除成功!\033[0m" - else - echo -e "你输入的地址是:\033[32m$input\033[0m" - read -p "确认添加?(1/0) > " res - [ "$res" = 1 ] && echo $input >>${CRASHDIR}/configs/fake_ip_filter - fi - sleep 1 - fake_ip_filter - ;; - esac -} -normal_set() { #基础设置 - #获取设置默认显示 - [ -z "$skip_cert" ] && skip_cert=已开启 - [ -z "$common_ports" ] && common_ports=已开启 - [ -z "$dns_mod" ] && dns_mod=fake-ip - [ -z "$dns_over" ] && dns_over=已开启 - [ -z "$cn_ip_route" ] && cn_ip_route=未开启 - [ -z "$local_proxy" ] && local_proxy=未开启 - [ -z "$quic_rj" ] && quic_rj=未开启 - [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ] && mac_return=未开启 || mac_return=已启用 - # - echo "-----------------------------------------------" - echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" - echo "-----------------------------------------------" - echo -e " 1 切换防火墙运行模式: \033[36m$redir_mod\033[0m" - [ "$disoverride" != "1" ] && { - echo -e " 2 切换DNS运行模式: \033[36m$dns_mod\033[0m" - echo -e " 3 跳过本地证书验证: \033[36m$skip_cert\033[0m ————解决节点证书验证错误" - } - echo -e " 4 只代理常用端口: \033[36m$common_ports\033[0m ————用于过滤P2P流量" - echo -e " 5 过滤局域网设备: \033[36m$mac_return\033[0m ————使用黑/白名单进行过滤" - echo -e " 7 屏蔽QUIC流量: \033[36m$quic_rj\033[0m ————优化视频性能" - [ "$disoverride" != "1" ] && { - [ "$dns_mod" != "fake-ip" ] && - echo -e " 8 CN_IP绕过内核: \033[36m$cn_ip_route\033[0m ————优化性能,不兼容Fake-ip" - [ "$dns_mod" != "redir_host" ] && - echo -e " 9 管理Fake-ip过滤列表" - } - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单 \033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) - i= - ;; - 1) - if [ "$USER" != "root" -a "$USER" != "admin" ]; then - echo "-----------------------------------------------" - read -p "非root用户可能无法正确配置其他模式!依然尝试吗?(1/0) > " res - [ "$res" = 1 ] && set_redir_mod - else - set_redir_mod - fi - normal_set - ;; - 2) - set_dns_mod - sleep 1 - normal_set - ;; - 3) - echo "-----------------------------------------------" - if [ "$skip_cert" = "未开启" ] >/dev/null 2>&1; then - echo -e "\033[33m已设为开启跳过本地证书验证!!\033[0m" - skip_cert=已开启 - else - echo -e "\033[33m已设为禁止跳过本地证书验证!!\033[0m" - skip_cert=未开启 - fi - setconfig skip_cert $skip_cert - normal_set - ;; - 4) - set_common_ports() { - if [ "$common_ports" = "未开启" ]; then - echo -e "\033[33m当前代理端口为:【$multiport】\033[0m" - echo -e "\033[31m注意,fake-ip模式下,非常用端口的域名连接将不受影响!!\033[0m" - read -p "是否修改默认端口?(1/0) > " res - [ "$res" = "1" ] && { - read -p "请输入自定义端口,注意用小写逗号分隔 > " text - [ -n "$text" ] && setconfig multiport $text && echo -e "\033[33m已设为代理【$multiport】端口!!\033[0m" - } - common_ports=已开启 - sleep 1 - else - echo -e "\033[33m已设为代理全部端口!!\033[0m" - common_ports=未开启 - fi - setconfig common_ports $common_ports - } - echo "-----------------------------------------------" - if [ -n "$(pidof CrashCore)" ]; then - read -p "切换时将停止服务,是否继续?(1/0) > " res - [ "$res" = 1 ] && ${CRASHDIR}/start.sh stop && set_common_ports - else - set_common_ports - fi - normal_set - ;; - 5) - checkcfg_mac=$(cat ${CRASHDIR}/configs/mac) - macfilter - if [ -n "$PID" ]; then - checkcfg_mac_new=$(cat ${CRASHDIR}/configs/mac) - [ "$checkcfg_mac" != "$checkcfg_mac_new" ] && checkrestart - fi - normal_set - ;; - 7) - echo "-----------------------------------------------" - if [ -n "$(echo "$redir_mod" | grep -oE '混合|Tproxy|Tun')" ]; then - if [ "$quic_rj" = "未开启" ]; then - echo -e "\033[33m已禁止QUIC流量通过ShellCrash内核!!\033[0m" - quic_rj=已启用 - else - echo -e "\033[33m已取消禁止QUIC协议流量!!\033[0m" - quic_rj=未开启 - fi - setconfig quic_rj $quic_rj - else - echo -e "\033[33m当前模式默认不会代理UDP流量,无需设置!!\033[0m" - fi - sleep 1 - normal_set - ;; - 8) - if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = 'nftables' ]; then - if [ "$cn_ip_route" = "未开启" ]; then - echo -e "\033[32m已开启CN_IP绕过内核功能!!\033[0m" - echo -e "\033[31m注意!!!此功能会导致全局模式及一切CN相关规则失效!!!\033[0m" - cn_ip_route=已开启 - sleep 2 - else - echo -e "\033[33m已禁用CN_IP绕过内核功能!!\033[0m" - cn_ip_route=未开启 - fi - setconfig cn_ip_route $cn_ip_route - else - echo -e "\033[31m当前设备缺少ipset模块或未使用nftables模式,无法启用绕过功能!!\033[0m" - sleep 1 - fi - normal_set - ;; - 9) - echo "-----------------------------------------------" - fake_ip_filter - normal_set - ;; - *) - errornum - ;; - esac -} -advanced_set() { #进阶设置 - #获取设置默认显示 - [ -z "$proxies_bypass" ] && proxies_bypass=未启用 - [ -z "$start_old" ] && start_old=未开启 - [ -z "$tproxy_mod" ] && tproxy_mod=未开启 - [ -z "$public_support" ] && public_support=未开启 - [ -z "$sniffer" ] && sniffer=未启用 - [ "$crashcore" = "clashpre" ] && [ "$dns_mod" = "redir_host" ] && sniffer=已启用 - [ "$BINDIR" = "/tmp/ShellCrash" ] && mini_clash=已开启 || mini_clash=未开启 - # - echo "-----------------------------------------------" - echo -e "\033[30;47m欢迎使用进阶模式菜单:\033[0m" - echo -e "\033[33m如您并不了解ShellCrash的运行机制,请勿更改本页面功能!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 访问与控制" - echo -e " 3 配置公网及局域网防火墙" - [ "$disoverride" != "1" ] && { - echo -e " 4 启用域名嗅探: \033[36m$sniffer\033[0m ————用于流媒体及防DNS污染" - echo -e " 5 自定义\033[32m端口及秘钥\033[0m" - } - echo "-----------------------------------------------" - echo -e " 9 \033[31m重置/备份/还原\033[0m脚本设置" - echo -e " 0 返回上级菜单 \033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - . "$CRASHDIR"/menus/gateway.sh && gateway - advanced_set - ;; - 3) - setfirewall - advanced_set - ;; - 4) - echo "-----------------------------------------------" - if [ "$sniffer" = "未启用" ]; then - if [ "$crashcore" = "clash" ]; then - rm -rf ${TMPDIR}/CrashCore - rm -rf ${CRASHDIR}/CrashCore - rm -rf ${CRASHDIR}/CrashCore.tar.gz - crashcore=meta - setconfig crashcore $crashcore - echo "已将ShellCrash内核切换为Meta内核!域名嗅探依赖Meta或者高版本clashpre内核!" - fi - sniffer=已启用 - elif [ "$crashcore" = "clashpre" -a "$dns_mod" = "redir_host" ]; then - echo -e "\033[31m使用clashpre内核且开启redir-host模式时无法关闭!\033[0m" - else - sniffer=未启用 - fi - setconfig sniffer $sniffer - echo -e "\033[32m设置成功!\033[0m" - sleep 1 - advanced_set - ;; - 5) - if [ -n "$(pidof CrashCore)" ]; then - echo "-----------------------------------------------" - echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" - read -p "是否停止服务?(1/0) > " res - if [ "$res" = "1" ]; then - ${CRASHDIR}/start.sh stop - setport - fi - else - setport - fi - advanced_set - ;; - 9) - echo -e " 1 备份脚本设置" - echo -e " 2 还原脚本设置" - echo -e " 3 重置脚本设置" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= - elif [ "$num" = 1 ]; then - cp -f $CFG_PATH $CFG_PATH.bak - echo -e "\033[32m脚本设置已备份!\033[0m" - elif [ "$num" = 2 ]; then - if [ -f "$CFG_PATH.bak" ]; then - mv -f $CFG_PATH $CFG_PATH.bak2 - mv -f $CFG_PATH.bak $CFG_PATH - mv -f $CFG_PATH.bak2 $CFG_PATH.bak - echo -e "\033[32m脚本设置已还原!(被覆盖的配置已备份!)\033[0m" - else - echo -e "\033[31m找不到备份文件,请先备份脚本设置!\033[0m" - fi - elif [ "$num" = 3 ]; then - mv -f $CFG_PATH $CFG_PATH.bak - . ${CRASHDIR}/init.sh >/dev/null - echo -e "\033[32m脚本设置已重置!(旧文件已备份!)\033[0m" - fi - echo -e "\033[33m请重新启动脚本!\033[0m" - exit 0 - ;; - *) errornum ;; - esac -} -#工具脚本 -autoSSH() { - echo "-----------------------------------------------" - echo -e "\033[33m本功能使用软件命令进行固化不保证100%成功!\033[0m" - echo -e "\033[33m如有问题请加群反馈:\033[36;4mhttps://t.me/ShellClash\033[0m" - read -p "请输入需要还原的SSH密码(不影响当前密码,回车可跳过) > " mi_autoSSH_pwd - mi_autoSSH=已配置 - cp -f /etc/dropbear/dropbear_rsa_host_key ${CRASHDIR}/configs/dropbear_rsa_host_key 2>/dev/null - cp -f /etc/dropbear/authorized_keys ${CRASHDIR}/configs/authorized_keys 2>/dev/null - ckcmd nvram && { - nvram set ssh_en=1 - nvram set telnet_en=1 - nvram set uart_en=1 - nvram set boot_wait=on - nvram commit - } - echo -e "\033[32m设置成功!\033[0m" - setconfig mi_autoSSH $mi_autoSSH - setconfig mi_autoSSH_pwd $mi_autoSSH_pwd - sleep 1 -} +#卸载 uninstall() { read -p "确认卸载ShellCrash?(警告:该操作不可逆!)[1/0] > " res if [ "$res" = '1' ]; then #停止服务 - ${CRASHDIR}/start.sh stop 2>/dev/null - ${CRASHDIR}/start.sh cronset "clash服务" 2>/dev/null - ${CRASHDIR}/start.sh cronset "订阅链接" 2>/dev/null - ${CRASHDIR}/start.sh cronset "ShellCrash初始化" 2>/dev/null - ${CRASHDIR}/start.sh cronset "task.sh" 2>/dev/null + "$CRASHDIR"/start.sh stop 2>/dev/null + "$CRASHDIR"/start.sh cronset "clash服务" 2>/dev/null + "$CRASHDIR"/start.sh cronset "订阅链接" 2>/dev/null + "$CRASHDIR"/start.sh cronset "ShellCrash初始化" 2>/dev/null + "$CRASHDIR"/start.sh cronset "task.sh" 2>/dev/null #移除安装目录 - if [ -n "${CRASHDIR}" ] && [ "${CRASHDIR}" != '/' ]; then + if [ -n "$CRASHDIR" ] && [ "$CRASHDIR" != '/' ]; then read -p "是否保留脚本配置及订阅文件?[1/0] > " res if [ "$res" = '1' ]; then - mv -f ${CRASHDIR}/configs /tmp/ShellCrash/configs_bak - mv -f ${CRASHDIR}/yamls /tmp/ShellCrash/yamls_bak - mv -f ${CRASHDIR}/jsons /tmp/ShellCrash/jsons_bak - rm -rf ${CRASHDIR}/* - mv -f /tmp/ShellCrash/configs_bak "${CRASHDIR}/configs" - mv -f /tmp/ShellCrash/yamls_bak "${CRASHDIR}/yamls" - mv -f /tmp/ShellCrash/jsons_bak "${CRASHDIR}/jsons" + mv -f "$CRASHDIR"/configs /tmp/ShellCrash/configs_bak + mv -f "$CRASHDIR"/yamls /tmp/ShellCrash/yamls_bak + mv -f "$CRASHDIR"/jsons /tmp/ShellCrash/jsons_bak + rm -rf "$CRASHDIR"/* + mv -f /tmp/ShellCrash/configs_bak "$CRASHDIR"/configs + mv -f /tmp/ShellCrash/yamls_bak "$CRASHDIR"/yamls + mv -f /tmp/ShellCrash/jsons_bak "$CRASHDIR"/jsons else - rm -rf ${CRASHDIR} + rm -rf "$CRASHDIR" fi else echo -e "\033[31m环境变量配置有误,请尝试手动移除安装目录!\033[0m" @@ -1984,7 +281,7 @@ uninstall() { sed -i "/启用外网访问SSH服务/d" /etc/firewall.user 2>/dev/null sed -i '/ShellCrash初始化/'d /etc/storage/started_script.sh 2>/dev/null sed -i '/ShellCrash初始化/'d /jffs/.asusrouter 2>/dev/null - [ "$BINDIR" != "$CRASHDIR" ] && rm -rf ${BINDIR} + [ "$BINDIR" != "$CRASHDIR" ] && rm -rf "$BINDIR" rm -rf /etc/init.d/shellcrash rm -rf /etc/systemd/system/shellcrash.service rm -rf /usr/lib/systemd/system/shellcrash.service @@ -2006,199 +303,20 @@ uninstall() { echo -e "\033[31m操作已取消!\033[0m" fi } -tools() { - ssh_tools() { - stop_iptables() { - iptables -w -t nat -D PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 - ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 - } - [ -n "$(cat /etc/firewall.user 2>&1 | grep '启用外网访问SSH服务')" ] && ssh_ol=禁止 || ssh_ol=开启 - [ -z "$ssh_port" ] && ssh_port=10022 - echo "-----------------------------------------------" - echo -e "\033[33m此功能仅针对使用Openwrt系统的设备生效,且不依赖服务\033[0m" - echo -e "\033[31m本功能不支持红米AX6S等镜像化系统设备,请勿尝试!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 \033[32m修改\033[0m外网访问端口:\033[36m$ssh_port\033[0m" - echo -e " 2 \033[32m修改\033[0mSSH访问密码(请连续输入2次后回车)" - echo -e " 3 \033[33m$ssh_ol\033[0m外网访问SSH" - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单 \033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - read -p "请输入端口号(1000-65535) > " num - if [ -z "$num" ]; then - errornum - elif [ $num -gt 65535 -o $num -le 999 ]; then - echo -e "\033[31m输入错误!请输入正确的数值(1000-65535)!\033[0m" - elif [ -n "$(netstat -ntul | grep :$num)" ]; then - echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" - else - ssh_port=$num - setconfig ssh_port $ssh_port - sed -i "/启用外网访问SSH服务/d" /etc/firewall.user - stop_iptables - echo -e "\033[32m设置成功,请重新开启外网访问SSH功能!!!\033[0m" - fi - sleep 1 - ssh_tools - ;; - 2) - passwd - sleep 1 - ssh_tools - ;; - 3) - if [ "$ssh_ol" = "开启" ]; then - iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 - [ -n "$(ckcmd ip6tables)" ] && ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 - echo "iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user - [ -n "$(ckcmd ip6tables)" ] && echo "ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user - echo "-----------------------------------------------" - echo -e "已开启外网访问SSH功能!" - else - sed -i "/启用外网访问SSH服务/d" /etc/firewall.user - stop_iptables - echo "-----------------------------------------------" - echo -e "已禁止外网访问SSH!" - fi - ;; - *) - errornum - ;; - esac - } - #获取设置默认显示 - grep -qE "^\s*[^#].*otapredownload" /etc/crontabs/root >/dev/null 2>&1 && mi_update=禁用 || mi_update=启用 - [ "$mi_autoSSH" = "已配置" ] && mi_autoSSH_type=32m已配置 || mi_autoSSH_type=31m未配置 - [ -f ${CRASHDIR}/tools/tun.ko ] && mi_tunfix=32m已启用 || mi_tunfix=31m未启用 - # - echo "-----------------------------------------------" - echo -e "\033[30;47m欢迎使用其他工具菜单:\033[0m" - echo -e "\033[33m本页工具可能无法兼容全部Linux设备,请酌情使用!\033[0m" - echo -e "磁盘占用/所在目录:" - du -sh ${CRASHDIR} - echo "-----------------------------------------------" - echo -e " 1 ShellCrash\033[33m测试菜单\033[0m" - echo -e " 2 ShellCrash\033[32m新手引导\033[0m" - echo -e " 3 \033[36m日志及推送工具\033[0m" - [ -f /etc/firewall.user ] && echo -e " 4 \033[32m配置\033[0m外网访问SSH" - [ -x /usr/sbin/otapredownload ] && echo -e " 5 \033[33m$mi_update\033[0m小米系统自动更新" - [ "$systype" = "mi_snapshot" ] && echo -e " 6 小米设备软固化SSH ———— \033[$mi_autoSSH_type \033[0m" - [ -f /etc/config/ddns ] && echo -e " 7 配置\033[32mDDNS服务\033[0m(需下载相关脚本)" - [ "$systype" = "mi_snapshot" ] && echo -e " 8 小米设备Tun模块修复 ———— \033[$mi_tunfix \033[0m" - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= - - elif [ "$num" = 1 ]; then - . ${CRASHDIR}/webget.sh && testcommand - - elif [ "$num" = 2 ]; then - . ${CRASHDIR}/webget.sh && userguide - - elif [ "$num" = 3 ]; then - log_pusher - tools - - elif [ "$num" = 4 ]; then - ssh_tools - sleep 1 - tools - - elif [ "$num" = 7 ]; then - echo "-----------------------------------------------" - if [ ! -f ${CRASHDIR}/tools/ShellDDNS.sh ]; then - echo -e "正在获取在线脚本……" - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/ShellDDNS.sh tools/ShellDDNS.sh - if [ "$?" = "0" ]; then - mv -f ${TMPDIR}/ShellDDNS.sh ${CRASHDIR}/tools/ShellDDNS.sh - . ${CRASHDIR}/tools/ShellDDNS.sh - else - echo -e "\033[31m文件下载失败!\033[0m" - fi - else - . ${CRASHDIR}/tools/ShellDDNS.sh - fi - sleep 1 - tools - - elif [ -x /usr/sbin/otapredownload ] && [ "$num" = 5 ]; then - if [ "$mi_update" = "禁用" ]; then - grep -q "otapredownload" /etc/crontabs/root && - sed -i "/^[^\#]*otapredownload/ s/^/#/" /etc/crontabs/root || - echo "#15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root - else - grep -q "otapredownload" /etc/crontabs/root && - sed -i "/^\s*#.*otapredownload/ s/^\s*#//" /etc/crontabs/root || - echo "15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root - fi - echo "-----------------------------------------------" - echo -e "已\033[33m$mi_update\033[0m小米路由器的自动更新,如未生效,请在官方APP中同步设置!" - sleep 1 - tools - - elif [ "$num" = 6 ]; then - if [ "$systype" = "mi_snapshot" ]; then - autoSSH - else - echo "不支持的设备!" - fi - tools - elif [ "$num" = 8 ]; then - if [ -f ${CRASHDIR}/tools/tun.ko ]; then - read -p "是否禁用此功能并移除相关补丁?(1/0) > " res - [ "$res" = 1 ] && { - rm -rf ${CRASHDIR}/tools/tun.ko - echo -e "\033[33m补丁文件已移除,请立即重启设备以防止出错!\033[0m" - } - elif ckcmd modinfo && [ -z "$(modinfo tun)" ]; then - echo -e "\033[33m本功能需要修改系统文件,不保证没有任何风险!\033[0m" - echo -e "\033[33m本功能采集的Tun模块并不一定适用于你的设备!\033[0m" - sleep 1 - read -p "我已知晓,出现问题会自行承担!(1/0) > " res - if [ "$res" = 1 ]; then - echo "-----------------------------------------------" - echo "正在连接服务器获取Tun模块补丁文件…………" - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/tun.ko bin/fix/tun.ko - if [ "$?" = "0" ]; then - mv -f ${TMPDIR}/tun.ko ${CRASHDIR}/tools/tun.ko && - ${CRASHDIR}/misnap_init.sh tunfix && - echo -e "\033[32m设置成功!请重启服务!\033[0m" - else - echo -e "\033[31m文件下载失败,请重试!\033[0m" - fi - fi - else - echo -e "\033[31m当前设备无需设置,请勿尝试!\033[0m" - sleep 1 - fi - tools - else - errornum - fi -} #主菜单 main_menu() { ############################# ckstatus ############################# - echo -e " 1 \033[32m启动/重启\033[0m服务" - echo -e " 2 内核\033[33m功能设置\033[0m" - echo -e " 3 \033[31m停止\033[0m内核服务" - echo -e " 4 内核\033[36m启动设置\033[0m" - echo -e " 5 配置\033[33m自动任务\033[0m" - echo -e " 6 导入\033[32m配置文件\033[0m" - echo -e " 7 内核\033[31m进阶设置\033[0m" - echo -e " 8 \033[35m其他工具\033[0m" - echo -e " 9 \033[36m更新/卸载\033[0m" + echo -e " 1 \033[32m启动/重启服务\033[0m" + echo -e " 2 \033[36m功能设置\033[0m" + echo -e " 3 \033[31m停止服务\033[0m" + echo -e " 4 \033[33m启动设置\033[0m" + echo -e " 5 设置\033[32m自动任务\033[0m" + echo -e " 6 管理\033[36m配置文件\033[0m" + echo -e " 7 \033[33m访问与控制\033[0m" + echo -e " 8 \033[0m工具与优化\033[0m" + echo -e " 9 \033[32m更新与支持\033[0m" echo "-----------------------------------------------" echo -e " 0 \033[0m退出脚本\033[0m" read -p "请输入对应数字 > " num @@ -2206,65 +324,67 @@ main_menu() { case "$num" in 0) exit - ;; + ;; 1) start_service exit - ;; + ;; 2) - checkcfg=$(cat $CFG_PATH) - . "$CRASHDIR"/menus/normal_set.sh && normal_set + checkcfg=$(cat "$CFG_PATH") + . "$CRASHDIR"/menus/settings.sh && settings if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) + checkcfg_new=$(cat "$CFG_PATH") [ "$checkcfg" != "$checkcfg_new" ] && checkrestart fi main_menu - ;; + ;; 3) - ${CRASHDIR}/start.sh stop + "$CRASHDIR"/start.sh stop sleep 1 echo "-----------------------------------------------" echo -e "\033[31m$corename服务已停止!\033[0m" main_menu - ;; + ;; 4) - setboot + . "$CRASHDIR"/menus/setboot.sh && setboot main_menu - ;; + ;; 5) - . ${CRASHDIR}/task/task.sh && task_menu + . "$CRASHDIR"/menus/task.sh && task_menu main_menu - ;; + ;; 6) - . ${CRASHDIR}/webget.sh && set_core_config + . "$CRASHDIR"/menus/core_config.sh && set_core_config main_menu - ;; + ;; 7) - checkcfg=$(cat $CFG_PATH) - advanced_set + GT_CFG_PATH="$CRASHDIR"/configs/gateway.cfg + touch "$GT_CFG_PATH" + checkcfg=$(cat $GT_CFG_PATH) + . "$CRASHDIR"/menus/gateway.sh && gateway if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) + checkcfg_new=$(cat $GT_CFG_PATH) [ "$checkcfg" != "$checkcfg_new" ] && checkrestart fi main_menu - ;; + ;; 8) - tools + . "$CRASHDIR"/menus/tools.sh && tools main_menu - ;; + ;; 9) - checkcfg=$(cat $CFG_PATH) - . ${CRASHDIR}/webget.sh && update + checkcfg=$(cat "$CFG_PATH") + . "$CRASHDIR"/menus/upgrade.sh && upgrade if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) + checkcfg_new=$(cat "$CFG_PATH") [ "$checkcfg" != "$checkcfg_new" ] && checkrestart fi main_menu - ;; + ;; *) errornum exit - ;; + ;; esac } @@ -2274,7 +394,7 @@ main_menu() { cd $(dirname $0) pwd ) - . ${CRASHDIR}/init.sh + . "$CRASHDIR"/init.sh sleep 1 echo "请重启SSH窗口以完成初始化!" exit @@ -2304,38 +424,38 @@ case "$1" in ;; -t) shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash - $shtype -x ${CRASHDIR}/menu.sh + $shtype -x "$CRASHDIR"/menu.sh ;; -s) - ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 + "$CRASHDIR"/start.sh $2 $3 $4 $5 $6 ;; -i) - . ${CRASHDIR}/init.sh + . "$CRASHDIR"/init.sh ;; -st) shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash - $shtype -x ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 + $shtype -x "$CRASHDIR"/start.sh $2 $3 $4 $5 $6 ;; -d) shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash echo -e "正在测试运行!如发现错误请截图后前往\033[32;4mt.me/ShellClash\033[0m咨询" - $shtype ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh_bug.log - $shtype -x ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh.log + $shtype "$CRASHDIR"/start.sh debug >/dev/null 2>"$TMPDIR"/debug_sh_bug.log + $shtype -x "$CRASHDIR"/start.sh debug >/dev/null 2>"$TMPDIR"/debug_sh.log echo ----------------------------------------- - cat ${TMPDIR}/debug_sh_bug.log | grep 'start\.sh' >${TMPDIR}/sh_bug - if [ -s ${TMPDIR}/sh_bug ]; then + cat "$TMPDIR"/debug_sh_bug.log | grep 'start\.sh' >"$TMPDIR"/sh_bug + if [ -s "$TMPDIR"/sh_bug ]; then while read line; do echo -e "发现错误:\033[33;4m$line\033[0m" - grep -A 1 -B 3 "$line" ${TMPDIR}/debug_sh.log + grep -A 1 -B 3 "$line" "$TMPDIR"/debug_sh.log echo ----------------------------------------- - done <${TMPDIR}/sh_bug - rm -rf ${TMPDIR}/sh_bug - echo -e "\033[32m测试完成!\033[0m完整执行记录请查看:\033[36m${TMPDIR}/debug_sh.log\033[0m" + done <"$TMPDIR"/sh_bug + rm -rf "$TMPDIR"/sh_bug + echo -e "\033[32m测试完成!\033[0m完整执行记录请查看:\033[36m$TMPDIR/debug_sh.log\033[0m" else echo -e "\033[32m测试完成!没有发现问题,请重新启动服务~\033[0m" - rm -rf ${TMPDIR}/debug_sh.log + rm -rf "$TMPDIR"/debug_sh.log fi - ${CRASHDIR}/start.sh stop + "$CRASHDIR"/start.sh stop ;; -u) uninstall diff --git a/scripts/menus/check_port.sh b/scripts/menus/check_port.sh index 76ca118d..6fb1122d 100644 --- a/scripts/menus/check_port.sh +++ b/scripts/menus/check_port.sh @@ -1,17 +1,17 @@ #!/bin/sh # Copyright (C) Juewuy - -if [ $1 -gt 65535 -o $1 -le 1 ]; then - echo -e "\033[31m输入错误!请输入正确的数值(1-65535)!\033[0m" - exit 1 -elif [ -n "$(echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep "|$1|")" ]; then - echo -e "\033[31m输入错误!请不要输入重复的端口!\033[0m" - exit 1 -elif [ -n "$(netstat -ntul | grep ":$1 ")" ]; then - echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" - exit 1 -else - exit 0 -fi - +check_port(){ + if [ "$1" -gt 65535 -o "$1" -le 1 ]; then + echo -e "\033[31m输入错误!请输入正确的数值(1-65535)!\033[0m" + return 1 + elif [ -n "$(echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep "|$1|")" ]; then + echo -e "\033[31m输入错误!请不要输入重复的端口!\033[0m" + return 1 + elif [ -n "$(netstat -ntul | grep ":$1 ")" ]; then + echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" + return 1 + else + return 0 + fi +} diff --git a/scripts/menus/core_config.sh b/scripts/menus/core_config.sh new file mode 100644 index 00000000..d1d1ebc2 --- /dev/null +++ b/scripts/menus/core_config.sh @@ -0,0 +1,1177 @@ +#!/bin/sh +# Copyright (C) Juewuy + +#导入订阅、配置文件相关 +setrules(){ #自定义规则 + set_rule_type(){ + echo "-----------------------------------------------" + echo -e "\033[33m请选择规则类型\033[0m" + echo $rule_type | awk -F ' ' '{for(i=1;i<=NF;i++){print i" "$i}}' + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + [0-9]*) + if [ $num -gt $(echo $rule_type | awk -F " " '{print NF}') ];then + errornum + else + rule_type_set=$(echo $rule_type|cut -d' ' -f$num) + echo "-----------------------------------------------" + echo -e "\033[33m请输入规则语句,可以是域名、泛域名、IP网段或者其他匹配规则类型的内容\033[0m" + read -p "请输入对应规则 > " rule_state_set + [ -n "$rule_state_set" ] && set_group_type || errornum + fi + ;; + *) + errornum + ;; + esac + } + set_group_type(){ + echo "-----------------------------------------------" + echo -e "\033[36m请选择具体规则\033[0m" + echo -e "\033[33m此处规则读取自现有配置文件,如果你后续更换配置文件时运行出错,请尝试重新添加\033[0m" + echo $rule_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + [0-9]*) + if [ $num -gt $(echo $rule_group | awk -F "#" '{print NF}') ];then + errornum + else + rule_group_set=$(echo $rule_group|cut -d'#' -f$num) + rule_all="- ${rule_type_set},${rule_state_set},${rule_group_set}" + [ -n "$(echo IP-CIDR SRC-IP-CIDR IP-CIDR6|grep "$rule_type_set")" ] && rule_all="${rule_all},no-resolve" + echo $rule_all >> $YAMLSDIR/rules.yaml + echo "-----------------------------------------------" + echo -e "\033[32m添加成功!\033[0m" + fi + ;; + *) + errornum + ;; + esac + } + del_rule_type(){ + echo -e "输入对应数字即可移除相应规则:" + sed -i '/^ *$/d; /^#/d' $YAMLSDIR/rules.yaml + cat $YAMLSDIR/rules.yaml | grep -Ev '^#' | awk -F "#" '{print " "NR" "$1$2$3}' + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + '') ;; + *) + if [ "$num" -le "$(wc -l < $YAMLSDIR/rules.yaml)" ];then + sed -i "${num}d" $YAMLSDIR/rules.yaml + sleep 1 + del_rule_type + else + errornum + fi + ;; + esac + } + get_rule_group(){ + "$CRASHDIR"/start.sh get_save http://127.0.0.1:${db_port}/proxies | sed 's/:{/!/g' | awk -F '!' '{for(i=1;i<=NF;i++) print $i}' | grep -aE '"Selector|URLTest|LoadBalance"' | grep -aoE '"name":.*"now":".*",' | awk -F '"' '{print "#"$4}' | tr -d '\n' + } + echo "-----------------------------------------------" + echo -e "\033[33m你可以在这里快捷管理自定义规则\033[0m" + echo -e "如需批量操作,请手动编辑:\033[36m $YAMLSDIR/rules.yaml\033[0m" + echo -e "\033[33msingbox和clash共用此处规则,可无缝切换!\033[0m" + echo -e "大量规则请尽量使用rule-set功能添加,\033[31m此处过量添加可能导致启动卡顿!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 新增自定义规则" + echo -e " 2 移除自定义规则" + echo -e " 3 清空规则列表" + echo "$crashcore" | grep -q 'singbox' || echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + rule_type="DOMAIN-SUFFIX DOMAIN-KEYWORD IP-CIDR SRC-IP-CIDR DST-PORT SRC-PORT GEOIP GEOSITE IP-CIDR6 DOMAIN PROCESS-NAME" + rule_group="DIRECT#REJECT$(get_rule_group)" + set_rule_type + setrules + ;; + 2) + echo "-----------------------------------------------" + if [ -s $YAMLSDIR/rules.yaml ];then + del_rule_type + else + echo -e "请先添加自定义规则!" + sleep 1 + fi + setrules + ;; + 3) + read -p "确认清空全部自定义规则?(1/0) > " res + [ "$res" = "1" ] && sed -i '/^\s*[^#]/d' $YAMLSDIR/rules.yaml + setrules + ;; + 4) + echo "-----------------------------------------------" + if [ "$proxies_bypass" = "未启用" ];then + echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" + echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" + read -p "启用节点绕过?(1/0) > " res + [ "$res" = "1" ] && proxies_bypass=已启用 + else + proxies_bypass=未启用 + fi + setconfig proxies_bypass $proxies_bypass + sleep 1 + setrules + ;; + *) + errornum + ;; + esac +} +setgroups(){ #自定义clash策略组 + set_group_type(){ + echo "-----------------------------------------------" + echo -e "\033[33m注意策略组名称必须和【自定义规则】或【自定义节点】功能中指定的策略组一致!\033[0m" + echo -e "\033[33m建议先创建策略组,之后可在【自定义规则】或【自定义节点】功能中智能指定\033[0m" + echo -e "\033[33m如需在当前策略组下添加节点,请手动编辑$YAMLSDIR/proxy-groups.yaml\033[0m" + read -p "请输入自定义策略组名称(不支持纯数字且不要包含特殊字符!) > " new_group_name + echo "-----------------------------------------------" + echo -e "\033[32m请选择策略组【$new_group_name】的类型!\033[0m" + echo $group_type_cn | awk '{for(i=1;i<=NF;i++){print i" "$i}}' + read -p "请输入对应数字 > " num + new_group_type=$(echo $group_type | awk '{print $'"$num"'}') + if [ "$num" = "1" ];then + unset new_group_url interval + else + read -p "请输入测速地址,回车则默认使用https://www.gstatic.com/generate_204 > " new_group_url + [ -z "$new_group_url" ] && new_group_url=https://www.gstatic.com/generate_204 + new_group_url="url: '$new_group_url'" + interval="interval: 300" + fi + set_group_add + #添加自定义策略组 + cat >> $YAMLSDIR/proxy-groups.yaml < " char + case "$char" in + 0) ;; + *) + for num in $char;do + rule_group_set=$(echo $proxy_group|cut -d'#' -f$num) + rule_group_add="${rule_group_add}#${rule_group_set}" + done + if [ -n "$rule_group_add" ];then + new_group_name="$new_group_name$rule_group_add" + unset rule_group_add + else + errornum + fi + ;; + esac + } + echo "-----------------------------------------------" + echo -e "\033[33m你可以在这里快捷管理自定义策略组\033[0m" + echo -e "\033[36m如需修改或批量操作,请手动编辑:$YAMLSDIR/proxy-groups.yaml\033[0m" + echo "-----------------------------------------------" + echo -e " 1 添加自定义策略组" + echo -e " 2 查看自定义策略组" + echo -e " 3 清空自定义策略组" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + group_type="select url-test fallback load-balance" + group_type_cn="手动选择 自动选择 故障转移 负载均衡" + proxy_group="$(cat $YAMLSDIR/proxy-groups.yaml $YAMLSDIR/config.yaml 2>/dev/null | sed "/#自定义策略组开始/,/#自定义策略组结束/d" | grep -Ev '^#' | grep -o '\- name:.*' | sed 's/#.*//' | sed 's/- name: /#/g' | tr -d '\n' | sed 's/#//')" + set_group_type + setgroups + ;; + 2) + echo "-----------------------------------------------" + cat $YAMLSDIR/proxy-groups.yaml + setgroups + ;; + 3) + read -p "确认清空全部自定义策略组?(1/0) > " res + [ "$res" = "1" ] && echo '#用于添加自定义策略组' > $YAMLSDIR/proxy-groups.yaml + setgroups + ;; + *) + errornum + ;; + esac +} +setproxies(){ #自定义clash节点 + set_proxy_type(){ + echo "-----------------------------------------------" + echo -e "\033[33m注意节点格式必须是单行,不包括括号,name:必须写在最前,例如:\033[0m" + echo -e "\033[36m【name: \"test\", server: 192.168.1.1, port: 12345, type: socks5, udp: true】\033[0m" + echo -e "更多写法请参考:\033[32m https://juewuy.github.io/ \033[0m" + read -p "请输入节点 > " proxy_state_set + if [ -n "$(echo $proxy_state_set | grep "#" )" ];then + echo -e "\033[33m绝对禁止包含【#】号!!!\033[0m" + elif [ -n "$(echo $proxy_state_set | grep -E "^name:" )" ];then + set_group_add + else + errornum + fi + } + set_group_add(){ + echo "-----------------------------------------------" + echo -e "\033[36m请选择想要将节点添加到的策略组\033[0m" + echo -e "\033[32m如需添加到多个策略组,请一次性输入多个数字并用空格隔开\033[0m" + echo -e "\033[33m如需自定义策略组,请先使用【管理自定义策略组功能】添加\033[0m" + echo "-----------------------------------------------" + echo $proxy_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字(多个用空格隔开) > " char + case "$char" in + 0) ;; + *) + for num in $char;do + rule_group_set=$(echo $proxy_group|cut -d'#' -f$num) + rule_group_add="${rule_group_add}#${rule_group_set}" + done + if [ -n "$rule_group_add" ];then + echo "- {$proxy_state_set}$rule_group_add" >> $YAMLSDIR/proxies.yaml + echo "-----------------------------------------------" + echo -e "\033[32m添加成功!\033[0m" + unset rule_group_add + else + errornum + fi + ;; + esac + } + echo "-----------------------------------------------" + echo -e "\033[33m你可以在这里快捷管理自定义节点\033[0m" + echo -e "\033[36m如需批量操作,请手动编辑:$YAMLSDIR/proxies.yaml\033[0m" + echo "-----------------------------------------------" + echo -e " 1 添加自定义节点" + echo -e " 2 管理自定义节点" + echo -e " 3 清空自定义节点" + echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + proxy_type="DOMAIN-SUFFIX DOMAIN-KEYWORD IP-CIDR SRC-IP-CIDR DST-PORT SRC-PORT GEOIP GEOSITE IP-CIDR6 DOMAIN MATCH" + proxy_group="$(cat $YAMLSDIR/proxy-groups.yaml $YAMLSDIR/config.yaml 2>/dev/null | sed "/#自定义策略组开始/,/#自定义策略组结束/d" | grep -Ev '^#' | grep -o '\- name:.*' | sed 's/#.*//' | sed 's/- name: /#/g' | tr -d '\n' | sed 's/#//')" + set_proxy_type + setproxies + ;; + 2) + echo "-----------------------------------------------" + sed -i '/^ *$/d' $YAMLSDIR/proxies.yaml 2>/dev/null + if [ -s $YAMLSDIR/proxies.yaml ];then + echo -e "当前已添加的自定义节点为:" + cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | awk -F '[,,}]' '{print NR, $1, $NF}' | sed 's/- {//g' + echo "-----------------------------------------------" + echo -e "\033[33m输入节点对应数字可以移除对应节点\033[0m" + read -p "请输入对应数字 > " num + if [ $num -le $(cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | wc -l) ];then + sed -i "$num{/^\s*[^#]/d}" $YAMLSDIR/proxies.yaml + else + errornum + fi + else + echo -e "请先添加自定义节点!" + sleep 1 + fi + setproxies + ;; + 3) + read -p "确认清空全部自定义节点?(1/0) > " res + [ "$res" = "1" ] && sed -i '/^\s*[^#]/d' $YAMLSDIR/proxies.yaml 2>/dev/null + setproxies + ;; + 4) + echo "-----------------------------------------------" + if [ "$proxies_bypass" = "未启用" ];then + echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" + echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" + read -p "启用节点绕过?(1/0) > " res + [ "$res" = "1" ] && proxies_bypass=已启用 + else + proxies_bypass=未启用 + fi + setconfig proxies_bypass $proxies_bypass + sleep 1 + setrules + ;; + *) + errornum + ;; + esac +} +gen_clash_providers(){ #生成clash的providers配置文件 + gen_clash_providers_txt(){ + if [ -n "$(echo $2|grep -E '^./')" ];then + local type=file + local path=$2 + local download_url= + else + local type=http + local path="./providers/${1}.yaml" + local download_url=$2 + fi + cat >> $TMPDIR/providers/providers.yaml <> $TMPDIR/providers/providers.yaml < ${TMPDIR}/providers/providers.yaml + #切割模版文件 + sed -n '/^proxy-groups:/,/^[a-z]/ { /^rule/d; p; }' ${TMPDIR}/provider_temp_file > ${TMPDIR}/providers/proxy-groups.yaml + sed -n '/^rule/,$p' ${TMPDIR}/provider_temp_file > ${TMPDIR}/providers/rules.yaml + rm -rf ${TMPDIR}/provider_temp_file + #生成providers模块 + if [ -n "$2" ];then + gen_clash_providers_txt $1 $2 + providers_tags=$1 + echo ' - {name: '${1}', type: url-test, tolerance: 100, lazy: true, use: ['${1}']}' >> ${TMPDIR}/providers/proxy-groups.yaml + else + providers_tags='' + while read line;do + tag=$(echo $line | awk '{print $1}') + url=$(echo $line | awk '{print $2}') + providers_tags=$(echo "$providers_tags, $tag" | sed 's/^, //') + gen_clash_providers_txt $tag $url + echo ' - {name: '${tag}', type: url-test, tolerance: 100, lazy: true, use: ['${tag}']}' >> ${TMPDIR}/providers/proxy-groups.yaml + done < ${CRASHDIR}/configs/providers.cfg + fi + #修饰模版文件并合并 + sed -i "s/{providers_tags}/$providers_tags/g" ${TMPDIR}/providers/proxy-groups.yaml + cut -c 1- ${TMPDIR}/providers/providers.yaml ${TMPDIR}/providers/proxy-groups.yaml ${TMPDIR}/providers/rules.yaml > ${TMPDIR}/config.yaml + rm -rf ${TMPDIR}/providers + #调用内核测试 + ${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml + if [ "$?" = 0 ];then + echo -e "\033[32m配置文件生成成功!\033[0m" + mkdir -p ${CRASHDIR}/yamls + mv -f ${TMPDIR}/config.yaml ${CRASHDIR}/yamls/config.yaml + read -p "是否立即启动/重启服务?(1/0) > " res + [ "$res" = 1 ] && { + start_core && $CRASHDIR/start.sh cronset '更新订阅' + exit + } + else + rm -rf ${TMPDIR}/CrashCore + rm -rf ${TMPDIR}/config.yaml + echo -e "\033[31m生成配置文件出错,请仔细检查输入!\033[0m" + fi +} +gen_singbox_providers(){ #生成singbox的providers配置文件 + gen_singbox_providers_txt(){ + if [ -n "$(echo $2|grep -E '^./')" ];then + cat >> ${TMPDIR}/providers/providers.json <> ${TMPDIR}/providers/providers.json <> ${TMPDIR}/providers/providers.json < ${TMPDIR}/providers/providers.json < ${TMPDIR}/providers/outbounds_add.json <> ${TMPDIR}/providers/outbounds_add.json + else + providers_tags='' + while read line;do + tag=$(echo $line | awk '{print $1}') + url=$(echo $line | awk '{print $2}') + providers_tags=$(echo "$providers_tags, \"$tag\"" | sed 's/^, //') + gen_singbox_providers_txt $tag $url + echo '{ "tag": "'${tag}'", "type": "urltest", "tolerance": 100, "providers": ["'${tag}'"], "include": ".*" },' >> ${TMPDIR}/providers/outbounds_add.json + done < ${CRASHDIR}/configs/providers.cfg + fi + #修复文件格式 + sed -i '$s/},/}]}/' ${TMPDIR}/providers/outbounds_add.json + sed -i '$s/},/}]}/' ${TMPDIR}/providers/providers.json + #使用模版生成outbounds和rules模块 + cat ${TMPDIR}/provider_temp_file | sed "s/{providers_tags}/$providers_tags/g" > ${TMPDIR}/providers/outbounds.json + rm -rf ${TMPDIR}/provider_temp_file + #调用内核测试 + ${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore merge ${TMPDIR}/config.json -C ${TMPDIR}/providers + if [ "$?" = 0 ];then + echo -e "\033[32m配置文件生成成功!如果启动超时建议更新里手动安装Singbox-srs数据库常用包!\033[0m" + mkdir -p ${CRASHDIR}/jsons + mv -f ${TMPDIR}/config.json ${CRASHDIR}/jsons/config.json + rm -rf ${TMPDIR}/providers + read -p "是否立即启动/重启服务?(1/0) > " res + [ "$res" = 1 ] && { + start_core && $CRASHDIR/start.sh cronset '更新订阅' + exit + } + else + echo -e "\033[31m生成配置文件出错,请仔细检查输入!\033[0m" + rm -rf ${TMPDIR}/CrashCore + rm -rf ${TMPDIR}/providers + fi +} +setproviders(){ #自定义providers + #获取模版名称 + if [ -z "$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg)" ];then + provider_temp_des=$(sed -n "1 p" ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print $1}') + else + provider_temp_file=$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg | awk -F '=' '{print $2}') + provider_temp_des=$(grep "$provider_temp_file" ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print $1}') + [ -z "$provider_temp_des" ] && provider_temp_des=$provider_temp_file + fi + echo "-----------------------------------------------" + echo -e "\033[33m你可以在这里快捷管理与生成自定义的providers服务商\033[0m" + echo -e "\033[33m支持在线及本地的Yaml格式配置导入\033[0m" + [ -s $CRASHDIR/configs/providers.cfg ] && { + echo "-----------------------------------------------" + echo -e "\033[36m输入对应数字可管理providers服务商\033[0m" + cat $CRASHDIR/configs/providers.cfg | awk -F "#" '{print " "NR" "$1" "$2}' + } + echo -e " d \033[31m清空\033[0mproviders服务商列表" + echo -e " e \033[33m清理\033[0mproviders目录文件" + echo "-----------------------------------------------" + echo -e "\033[36m按照a-b-c的顺序即可完成配置生成\033[0m" + echo -e " a \033[36m添加\033[0mproviders服务商/节点" + echo -e " b 选择\033[33m规则模版\033[0m \033[32m$provider_temp_des\033[0m" + echo -e " c \033[32m生成\033[0m基于providers的配置文件" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + read -p "请输入对应字母或数字 > " num + case "$num" in + 0) + ;; + [1-9]|[1-9][0-9]) + provider_name=$(sed -n "$num p" $CRASHDIR/configs/providers.cfg | awk '{print $1}') + provider_url=$(sed -n "$num p" $CRASHDIR/configs/providers.cfg | awk '{print $2}') + if [ -z "$provider_name" ];then + errornum + else + echo "-----------------------------------------------" + echo -e " 1 修改名称:\033[36m$provider_name\033[0m" + echo -e " 2 修改链接地址:\033[32m$provider_url\033[0m" + echo -e " 3 生成\033[33m仅包含此链接\033[0m的配置文件" + echo -e " 4 \033[31m移除此链接\033[0m" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + read -p "请选择需要执行的操作 > " num + case "$num" in + 0) + ;; + 1) + read -p "请输入名称或者代号(不可重复,不支持纯数字) > " name + if [ -n "$name" ] && [ -z "$(echo "$name" | grep -E '^[0-9]+$')" ] && ! grep -q "$name" $CRASHDIR/configs/providers.cfg;then + sed -i "s|$provider_name $provider_url|$name $provider_url|" $CRASHDIR/configs/providers.cfg + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + ;; + 2) + read -p "请输入链接地址或本地相对路径 > " link + if [ -n "$(echo $link | grep -E '.*\..*|^\./')" ] && [ -z "$(grep "$link" $CRASHDIR/configs/providers.cfg)" ];then + link=$(echo $link | sed 's/\&/\\\&/g') #特殊字符添加转义 + sed -i "s|$provider_name $provider_url|$provider_name $link|" $CRASHDIR/configs/providers.cfg + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + ;; + 3) + gen_${coretype}_providers $provider_name $provider_url + ;; + 4) + sed -i "/^$provider_name /d" $CRASHDIR/configs/providers.cfg + ;; + *) + errornum + ;; + esac + sleep 1 + fi + setproviders + ;; + a) + echo "-----------------------------------------------" + echo -e "支持填写在线的\033[32mYClash订阅地址\033[0m或者\033[32m本地Clash配置文件\033[0m" + echo -e "本地配置文件请放在\033[32m$CRASHDIR\033[0m目录下,并填写相对路径如【\033[32m./providers/test.yaml\033[0m】" + echo "-----------------------------------------------" + read -p "请输入链接地址或本地相对路径 > " link + link=$(echo $link | sed 's/ //g') #去空格 + [ -n "$(echo $link | grep -E '.*\..*|^\./')" ] && { + read -p "请输入名称或代号(不可重复,不支持纯数字) > " name + name=$(echo $name | sed 's/ //g') + [ -n "$name" ] && [ -z "$(echo "$name" | grep -E '^[0-9]+$')" ] && ! grep -q "$name" $CRASHDIR/configs/providers.cfg && { + echo "-----------------------------------------------" + echo -e "名称:\033[36m$name\033[0m" + echo -e "链接地址/路径:\033[32m$link\033[0m" + read -p "确认添加?(1/0) > " res + [ "$res" = 1 ] && { + echo "$name $link" >> $CRASHDIR/configs/providers.cfg + echo -e "\033[32mproviders已添加!\033[0m" + } + } + } + [ "$?" != 0 ] && echo -e "\033[31m输入错误,操作已取消!\033[0m" + sleep 1 + setproviders + ;; + c) + echo "-----------------------------------------------" + if [ -s $CRASHDIR/configs/providers.cfg ];then + echo -e "\033[33msingboxr与mihomo内核的providers配置文件不互通!\033[0m" + echo "-----------------------------------------------" + read -p "确认生成${coretype}配置文件?(1/0) > " res + [ "$res" = "1" ] && { + gen_${coretype}_providers + } + else + echo -e "\033[31m你还未添加链接或本地配置文件,请先添加!\033[0m" + sleep 1 + fi + setproviders + ;; + b) + echo "-----------------------------------------------" + echo -e "当前规则模版为:\033[32m$provider_temp_des\033[0m" + echo -e "\033[33m请选择在线模版:\033[0m" + echo "-----------------------------------------------" + cat ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print " "NR" "$1}' + echo "-----------------------------------------------" + echo -e " a 使用\033[36m本地模版\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应字母或数字 > " num + case "$num" in + 0) + ;; + a) + read -p "请输入模版的路径(绝对路径) > " dir + if [ -s $dir ];then + provider_temp_file=$dir + setconfig provider_temp_${coretype} $provider_temp_file + echo -e "\033[32m设置成功!\033[0m" + else + echo -e "\033[31m输入错误,找不到对应模版文件!\033[0m" + fi + sleep 1 + ;; + *) + provider_temp_file=$(sed -n "$num p" ${CRASHDIR}/configs/${coretype}_providers.list 2>/dev/null | awk '{print $2}') + if [ -z "$provider_temp_file" ];then + errornum + else + setconfig provider_temp_${coretype} $provider_temp_file + fi + ;; + esac + setproviders + ;; + d) + read -p "确认清空全部链接?(1/0) > " res + [ "$res" = "1" ] && rm -rf $CRASHDIR/configs/providers.cfg + setproviders + ;; + e) + echo -e "\033[33m将清空 $CRASHDIR/providers 目录下所有内容\033[0m" + read -p "是否继续?(1/0) > " res + [ "$res" = "1" ] && rm -rf $CRASHDIR/providers + setproviders + ;; + *) + errornum + ;; + esac +} + +set_clash_adv(){ #自定义clash高级规则 + [ ! -f $YAMLSDIR/user.yaml ] && cat > $YAMLSDIR/user.yaml < $YAMLSDIR/others.yaml < " num + case "$num" in + 0) + ;; + 1) + if [ -n "$(pidof CrashCore)" ];then + echo "-----------------------------------------------" + echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" + read -p "是否停止服务?(1/0) > " res + if [ "$res" = "1" ];then + ${CRASHDIR}/start.sh stop + setport + fi + else + setport + fi + override + ;; + 2) + setrules + override + ;; + 3) + setproxies + override + ;; + 4) + setgroups + override + ;; + 5) + echo "$crashcore" | grep -q 'singbox' && set_singbox_adv || set_clash_adv + sleep 3 + override + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[33m此功能可能会导致严重问题!启用后脚本中大部分功能都将禁用!!!\033[0m" + echo -e "如果你不是非常了解$crashcore的运行机制,切勿开启!\033[0m" + echo -e "\033[33m继续后如出现任何问题,请务必自行解决,一切提问恕不受理!\033[0m" + echo "-----------------------------------------------" + sleep 2 + read -p "我确认遇到问题可以自行解决[1/0] > " res + [ "$res" = '1' ] && { + disoverride=1 + setconfig disoverride $disoverride + echo "-----------------------------------------------" + echo -e "\033[32m设置成功!\033[0m" + } + override + ;; + *) + errornum + ;; + esac +} + +gen_link_config(){ #选择在线规则 + echo "-----------------------------------------------" + echo 当前使用规则为:$(grep -aE '^5' ${CRASHDIR}/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $2}') + grep -aE '^5' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$2$4}' + echo "-----------------------------------------------" + echo 0 返回上级菜单 + read -p "请输入对应数字 > " num + totalnum=$(grep -acE '^5' ${CRASHDIR}/configs/servers.list ) + if [ -z "$num" ] || [ "$num" -gt "$totalnum" ];then + errornum + elif [ "$num" = 0 ];then + echo + elif [ "$num" -le "$totalnum" ];then + #将对应标记值写入配置 + rule_link=$num + setconfig rule_link $rule_link + echo "-----------------------------------------------" + echo -e "\033[32m设置成功!返回上级菜单\033[0m" + fi +} +gen_link_server(){ #选择在线服务器 + echo "-----------------------------------------------" + echo -e "\033[36m以下为互联网采集的第三方服务器,具体安全性请自行斟酌!\033[0m" + echo -e "\033[32m感谢以下作者的无私奉献!!!\033[0m" + echo 当前使用后端为:$(grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}') + grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$3" "$2}' + echo "-----------------------------------------------" + echo 0 返回上级菜单 + read -p "请输入对应数字 > " num + totalnum=$(grep -acE '^3|^4' ${CRASHDIR}/configs/servers.list ) + if [ -z "$num" ] || [ "$num" -gt "$totalnum" ];then + errornum + elif [ "$num" = 0 ];then + echo + elif [ "$num" -le "$totalnum" ];then + #将对应标记值写入配置 + server_link=$num + setconfig server_link $server_link + echo "-----------------------------------------------" + echo -e "\033[32m设置成功!返回上级菜单\033[0m" + fi +} +gen_link_flt(){ #在线生成节点过滤 + [ -z "$exclude" ] && exclude="未设置" + echo "-----------------------------------------------" + echo -e "\033[33m当前过滤关键字:\033[47;30m$exclude\033[0m" + echo "-----------------------------------------------" + echo -e "\033[33m匹配关键字的节点会在导入时被【屏蔽】!!!\033[0m" + echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" + echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" + echo "-----------------------------------------------" + echo -e " 000 \033[31m删除\033[0m关键字" + echo -e " 回车 取消输入并返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入关键字 > " exclude + if [ "$exclude" = '000' ]; then + echo "-----------------------------------------------" + exclude='' + echo -e "\033[31m 已删除节点过滤关键字!!!\033[0m" + fi + setconfig exclude "'$exclude'" +} +gen_link_ele(){ #在线生成节点筛选 + [ -z "$include" ] && include="未设置" + echo "-----------------------------------------------" + echo -e "\033[33m当前筛选关键字:\033[47;30m$include\033[0m" + echo "-----------------------------------------------" + echo -e "\033[33m仅有匹配关键字的节点才会被【导入】!!!\033[0m" + echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" + echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" + echo "-----------------------------------------------" + echo -e " 000 \033[31m删除\033[0m关键字" + echo -e " 回车 取消输入并返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入关键字 > " include + if [ "$include" = '000' ]; then + echo "-----------------------------------------------" + include='' + echo -e "\033[31m 已删除节点匹配关键字!!!\033[0m" + fi + setconfig include "'$include'" +} +get_core_config(){ #调用工具下载 + ${CRASHDIR}/start.sh get_core_config + if [ "$?" = 0 ];then + if [ "$inuserguide" != 1 ];then + read -p "是否启动服务以使配置文件生效?(1/0) > " res + [ "$res" = 1 ] && start_core || main_menu + exit; + fi + fi +} +gen_core_config_link(){ #在线生成工具 + echo "-----------------------------------------------" + echo -e "\033[30;47m 欢迎使用在线生成配置文件功能!\033[0m" + echo "-----------------------------------------------" + #设置输入循环 + i=1 + while [ $i -le 99 ] + do + echo "-----------------------------------------------" + echo -e "\033[33m本功能依赖第三方在线subconverter服务实现,脚本本身不提供任何代理服务!\033[0m" + echo -e "\033[31m严禁使用本脚本从事任何非法活动,否则一切后果请自负!\033[0m" + echo "-----------------------------------------------" + echo -e "支持批量(<=99)导入订阅链接、分享链接" + echo "-----------------------------------------------" + echo -e " 1 \033[36m开始生成配置文件\033[0m(原文件将被备份)" + echo -e " 2 设置\033[31m节点过滤\033[0m关键字 \033[47;30m$exclude\033[0m" + echo -e " 3 设置\033[32m节点筛选\033[0m关键字 \033[47;30m$include\033[0m" + echo -e " 4 选取在线\033[33m配置规则模版\033[0m" + echo -e " 5 \033[0m选取在线生成服务器\033[0m" + echo -e " 0 \033[31m撤销输入并返回上级菜单\033[0m" + echo "-----------------------------------------------" + read -p "请直接输入第${i}个链接或对应数字选项 > " link + link=$(echo $link | sed 's/\&/%26/g') #处理分隔符 + test=$(echo $link | grep "://") + link=`echo ${link/\#*/''}` #删除链接附带的注释内容 + link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 + link=`echo ${link/*\&url\=/""}` #将完整链接还原成单一链接 + link=`echo ${link/\&config\=*/""}` #将完整链接还原成单一链接 + + if [ -n "$test" ];then + if [ -z "$Url_link" ];then + Url_link="$link" + else + Url_link="$Url_link"\|"$link" + fi + i=$((i+1)) + + elif [ "$link" = '1' ]; then + if [ -n "$Url_link" ];then + i=100 + #将用户链接写入配置 + setconfig Https + setconfig Url "'$Url_link'" + #获取在线yaml文件 + get_core_config + else + echo "-----------------------------------------------" + echo -e "\033[31m请先输入订阅或分享链接!\033[0m" + sleep 1 + fi + + elif [ "$link" = '2' ]; then + gen_link_flt + + elif [ "$link" = '3' ]; then + gen_link_ele + + elif [ "$link" = '4' ]; then + gen_link_config + + elif [ "$link" = '5' ]; then + gen_link_server + + elif [ "$link" = 0 ];then + Url_link="" + i=100 + + else + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的链接或者数字!\033[0m" + sleep 1 + fi + done +} +set_core_config_link(){ #直接导入配置 + echo "-----------------------------------------------" + echo -e "\033[32m仅限导入完整的配置文件链接!!!\033[0m" + echo "-----------------------------------------------" + echo -e "注意:\033[31m此功能不兼容“跳过证书验证”功能,部分老旧\n设备可能出现x509报错导致节点不通\033[0m" + echo -e "你也可以搭配在线订阅转换网站或者自建SubStore使用" + echo "$crashcore" | grep -q 'singbox' &&echo -e "singbox内核建议使用\033[32;4mhttps://subv.jwsc.eu.org/\033[0m转换" + echo "-----------------------------------------------" + echo -e "\033[33m0 返回上级菜单\033[0m" + echo "-----------------------------------------------" + read -p "请输入完整链接 > " link + test=$(echo $link | grep -iE "tp.*://" ) + link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 + link=`echo ${link//\&/\\\&}` #处理分隔符 + if [ -n "$link" -a -n "$test" ];then + echo "-----------------------------------------------" + echo -e 请检查输入的链接是否正确: + echo -e "\033[4;32m$link\033[0m" + read -p "确认导入配置文件?原配置文件将被备份![1/0] > " res + if [ "$res" = '1' ]; then + #将用户链接写入配置 + sed -i '/Url=*/'d $CFG_PATH + setconfig Https "'$link'" + setconfig Url + #获取在线yaml文件 + get_core_config + else + set_core_config_link + fi + elif [ "$link" = 0 ];then + i= + else + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的配置文件链接地址!!!\033[0m" + echo -e "\033[33m仅支持http、https、ftp以及ftps链接!\033[0m" + sleep 1 + set_core_config_link + fi +} +set_core_config(){ #配置文件功能 + [ -z "$rule_link" ] && rule_link=1 + [ -z "$server_link" ] && server_link=1 + echo "$crashcore" | grep -q 'singbox' && config_path=${JSONSDIR}/config.json || config_path=${YAMLSDIR}/config.yaml + echo "-----------------------------------------------" + echo -e "\033[30;47m ShellCrash配置文件管理\033[0m" + echo "-----------------------------------------------" + echo -e " 1 在线\033[32m生成配置文件\033[0m(基于Subconverter订阅转换)" + if [ -f "$CRASHDIR"/v2b_api.sh ];then + echo -e " 2 登录\033[33m获取订阅(推荐!)\033[0m" + else + echo -e " 2 在线\033[33m获取配置文件\033[0m(基于订阅提供者)" + fi + echo -e " 3 本地\033[32m生成配置文件\033[0m(基于内核providers,推荐!)" + echo -e " 4 本地\033[33m上传完整配置文件\033[0m" + echo -e " 5 设置\033[36m自动更新\033[0m" + echo -e " 6 \033[32m自定义\033[0m配置文件" + echo -e " 7 \033[33m更新\033[0m配置文件" + echo -e " 8 \033[36m还原\033[0m配置文件" + echo -e " 9 自定义浏览器UA \033[32m$user_agent\033[0m" + echo "-----------------------------------------------" + [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + if [ -n "$Url" ];then + echo "-----------------------------------------------" + echo -e "\033[33m检测到已记录的链接内容:\033[0m" + echo -e "\033[4;32m$Url\033[0m" + echo "-----------------------------------------------" + read -p "清空链接/追加导入?[1/0] > " res + if [ "$res" = '1' ]; then + Url_link="" + echo "-----------------------------------------------" + echo -e "\033[31m链接已清空!\033[0m" + else + Url_link=$Url + fi + fi + gen_core_config_link + set_core_config + ;; + 2) + if [ -f "$CRASHDIR"/v2b_api.sh ];then + . "$CRASHDIR"/v2b_api.sh + set_core_config + else + set_core_config_link + fi + set_core_config + ;; + 3) + if [ "$crashcore" = meta -o "$crashcore" = clashpre ];then + coretype=clash + setproviders + elif [ "$crashcore" = singboxr ];then + coretype=singbox + setproviders + else + echo -e "\033[33msingbox官方内核及Clash基础内核不支持此功能,请先更换内核!\033[0m" + sleep 1 + checkupdate && setcore + fi + set_core_config + ;; + 4) + echo "-----------------------------------------------" + echo -e "\033[33m请将本地配置文件上传到/tmp目录并重命名为config.yaml或者config.json\033[0m" + echo -e "\033[32m之后重新运行本脚本即可自动弹出导入提示!\033[0m" + exit + ;; + 5) + . ${CRASHDIR}/task/task.sh && task_menu + set_core_config + ;; + 6) + checkcfg=$(cat $CFG_PATH) + override + if [ -n "$PID" ];then + checkcfg_new=$(cat $CFG_PATH) + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + set_core_config + ;; + 7) + if [ -z "$Url" -a -z "$Https" ];then + echo "-----------------------------------------------" + echo -e "\033[31m没有找到你的配置文件/订阅链接!请先输入链接!\033[0m" + sleep 1 + set_core_config + else + echo "-----------------------------------------------" + echo -e "\033[33m当前系统记录的链接为:\033[0m" + echo -e "\033[4;32m$Url$Https\033[0m" + echo "-----------------------------------------------" + read -p "确认更新配置文件?[1/0] > " res + if [ "$res" = '1' ]; then + get_core_config + else + set_core_config + fi + fi + ;; + 8) + if [ ! -f ${config_path}.bak ];then + echo "-----------------------------------------------" + echo -e "\033[31m没有找到配置文件的备份!\033[0m" + set_core_config + else + echo "-----------------------------------------------" + echo -e 备份文件共有"\033[32m`wc -l < ${config_path}.bak`\033[0m"行内容,当前文件共有"\033[32m`wc -l < ${config_path}`\033[0m"行内容 + read -p "确认还原配置文件?此操作不可逆![1/0] > " res + if [ "$res" = '1' ]; then + mv ${config_path}.bak ${config_path} + echo "----------------------------------------------" + echo -e "\033[32m配置文件已还原!请手动重启服务!\033[0m" + sleep 1 + else + echo "-----------------------------------------------" + echo -e "\033[31m操作已取消!返回上级菜单!\033[0m" + set_core_config + fi + fi + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[36m如果6-1或者6-2无法正确获取配置文件时可以尝试使用\033[0m" + echo -e " 1 使用自动UA" + echo -e " 2 不使用UA" + echo -e " 3 使用自定义UA:\033[32m$user_agent\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + user_agent='' + ;; + 1) + user_agent='auto' + ;; + 2) + user_agent='none' + ;; + 3) + read -p "请输入自定义UA(不要包含空格和特殊符号!) > " text + [ -n "$text" ] && user_agent="$text" + ;; + *) + errornum + ;; + esac + [ "$num" -le 3 ] && setconfig user_agent "$user_agent" + set_core_config + ;; + *) + errornum + ;; + esac +} diff --git a/scripts/menus/ddns.sh b/scripts/menus/ddns.sh new file mode 100644 index 00000000..7c6663e1 --- /dev/null +++ b/scripts/menus/ddns.sh @@ -0,0 +1,179 @@ +#! /bin/bash +# Copyright (C) Juewuy + + +ddns_menu(){ + echo ----------------------------------------------- + echo -e "\033[30;46m欢迎使用DDNS!\033[0m" + load_ddns +} +add_ddns() { + cat >>$ddns_dir </dev/null 2>&1 & + sleep 3 + echo 服务已经添加! +} +set_ddns() { + echo ----------------------------------------------- + read -p "请输入你的域名 > " str + [ -z "$str" ] && domain=$domain || domain=$str + echo ----------------------------------------------- + read -p "请输入用户名或邮箱 > " str + [ -z "$str" ] && username=$username || username=$str + echo ----------------------------------------------- + read -p "请输入密码或令牌秘钥 > " str + [ -z "$str" ] && password=$password || password=$str + echo ----------------------------------------------- + read -p "请输入检测更新间隔(单位:分钟;默认为10) > " check_interval + [ -z "$check_interval" ] || [ "$check_interval" -lt 1 -o "$check_interval" -gt 1440 ] && check_interval=10 + echo ----------------------------------------------- + read -p "请输入强制更新间隔(单位:小时;默认为24) > " force_interval + [ -z "$force_interval" ] || [ "$force_interval" -lt 1 -o "$force_interval" -gt 240 ] && force_interval=24 + echo ----------------------------------------------- + echo -e "请核对如下信息:" + echo -e "服务商: \033[32m$service\033[0m" + echo -e "域名: \033[32m$domain\033[0m" + echo -e "用户名: \033[32m$username\033[0m" + echo -e "检测间隔: \033[32m$check_interval\033[0m" + echo ----------------------------------------------- + read -p "确认添加?(1/0) > " res + [ "$res" = 1 ] && add_ddns || set_ddns +} +set_ddns_service() { + services_dir=/etc/ddns/$serv + [ -s $services_dir ] || services_dir=/usr/share/ddns/list + echo ----------------------------------------------- + echo -e "\033[32m请选择服务提供商\033[0m" + cat $services_dir | grep -v '^#' | awk '{print " "NR" " $1}' + nr=$(cat $services_dir | grep -v '^#' | wc -l) + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + i= + elif [ "$num" -gt 0 -a "$num" -lt $nr ]; then + service_name=$(cat $services_dir | grep -v '^#' | awk '{print $1}' | sed -n "$num"p | sed 's/"//g') + service=$(echo $service_name | sed 's/\./_/g') + set_ddns + else + echo "输入错误,请重新输入!" + sleep 1 + set_ddns_service + fi +} +set_ddns_type() { + echo ----------------------------------------------- + echo -e "\033[32m请选择网络模式\033[0m" + echo -e " 1 \033[36mIPV4\033[0m" + echo -e " 2 \033[36mIPV6\033[0m" + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + i= + elif [ "$num" = 1 ]; then + use_ipv6=0 + serv=services + set_ddns_service + elif [ "$num" = 2 ]; then + use_ipv6=1 + serv=services_ipv6 + set_ddns_service + else + echo "输入错误,请重新输入!" + sleep 1 + set_ddns_type + fi +} +rev_ddns_service() { + enabled=$(uci show ddns.$service | grep 'enabled' | awk -F "=" '{print $2}' | tr -d "'\"") + [ "$enabled" = 1 ] && enabled_b="停用" || enabled_b="启用" + echo ----------------------------------------------- + echo -e " 1 \033[32m立即更新\033[0m" + echo -e " 2 编辑当前服务\033[0m" + echo -e " 3 $enabled_b当前服务" + echo -e " 4 移除当前服务" + echo -e " 5 查看运行日志" + echo -e " 0 返回上级菜单" + echo ----------------------------------------------- + read -p "请输入对应数字 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ "$num" = 1 ]; then + /usr/lib/ddns/dynamic_dns_updater.sh -S $service start >/dev/null 2>&1 & + sleep 3 + elif [ "$num" = 2 ]; then + domain=$(uci show ddns.$service | grep 'domain' | awk -F "=" '{print $2}' | tr -d "'\"") + username=$(uci show ddns.$service | grep 'username' | awk -F "=" '{print $2}' | tr -d "'\"") + password=$(uci show ddns.$service | grep 'password' | awk -F "=" '{print $2}' | tr -d "'\"") + service_name=$(uci show ddns.$service | grep 'service_name' | awk -F "=" '{print $2}' | tr -d "'\"") + uci delete ddns.$service + set_ddns + elif [ "$num" = 3 ]; then + [ "$enabled" = 1 ] && uci set ddns.$service.enabled='0' || uci set ddns.$service.enabled='1' && sleep 3 + uci commit ddns.$service + elif [ "$num" = 4 ]; then + uci delete ddns.$service + uci commit ddns.$service + elif [ "$num" = 5 ]; then + echo ----------------------------------------------- + cat /var/log/ddns/$service.log 2>/dev/null + sleep 1 + fi +} +load_ddns() { + ddns_dir=/etc/config/ddns + tmp_dir="$TMPDIR"/ddns + [ ! -f "$ddns_dir" ] && { + echo -e "\033[31m本脚本依赖OpenWrt内置的DDNS服务,当前设备无法运行,已退出!\033[0m" + sleep 1 + return 1 + } + nr=0 + cat $ddns_dir | grep 'config service' | awk '{print $3}' | sed "s/\'//g" | sed "s/\"//g" >$tmp_dir + echo ----------------------------------------------- + echo -e "列表 域名 启用 IP地址" + echo ----------------------------------------------- + for service in $(cat $tmp_dir); do + #echo $service >>$tmp_dir + nr=$((nr + 1)) + enabled=$(uci show ddns.$service 2>/dev/null | grep 'enabled' | awk -F "=" '{print $2}' | tr -d "'\"") + domain=$(uci show ddns.$service 2>/dev/null | grep 'domain' | awk -F "=" '{print $2}' | tr -d "'\"") + local_ip=$(sed '1!G;h;$!d' /var/log/ddns/$service.log 2>/dev/null | grep -E 'Registered IP' | tail -1 | awk -F "'" '{print $2}' | tr -d "'\"") + echo -e " $nr $domain $enabled $local_ip" + done + echo -e " $((nr + 1)) 添加DDNS服务" + echo -e " 0 退出" + echo ----------------------------------------------- + read -p "请输入对应序号 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ "$num" -gt $nr ]; then + set_ddns_type + load_ddns + elif [ "$num" -gt 0 -a "$num" -le $nr ]; then + service=$(cat $tmp_dir | sed -n "$num"p) + rev_ddns_service + load_ddns + else + echo "请输入正确数字!" && load_ddns + fi + rm -rf $tmp_dir +} + + diff --git a/scripts/menus/dns.sh b/scripts/menus/dns.sh new file mode 100644 index 00000000..64d3a0c1 --- /dev/null +++ b/scripts/menus/dns.sh @@ -0,0 +1,258 @@ +#!/bin/sh +# Copyright (C) Juewuy + +set_dns_mod() { #DNS模式设置 + echo "-----------------------------------------------" + echo -e "当前DNS运行模式为:\033[47;30m $dns_mod \033[0m" + echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 fake-ip模式: 响应快,\033[33m兼容性较差\033[0m" + echo -e " 不支持CN-IP绕过功能" + echo -e " 2 redir_host模式:\033[33m不安全,易被污染\033[0m" + echo -e " 建议搭配第三方DNS服务使用" + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + echo -e " 3 mix混合模式: \033[32m防污染防泄露,响应快,推荐!\033[0m" + echo -e " cn域名realip其他fakeip分流" + echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" + echo -e " cn域名realip其他dns2proxy分流" + fi + [ "$dns_mod" = "fake-ip" ] || [ "$dns_mod" = "mix" ] && + echo -e " 8 管理Fake-ip过滤列表" + echo -e " 9 \033[36mDNS进阶设置\033[0m" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + dns_mod=fake-ip + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + set_dns_mod + ;; + 2) + dns_mod=redir_host + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + set_dns_mod + ;; + 3) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=mix + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + set_dns_mod + ;; + 4) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=route + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + set_dns_mod + ;; + 8) + echo "-----------------------------------------------" + fake_ip_filter + set_dns_mod + ;; + 9) + set_dns_adv + set_dns_mod + ;; + *) + errornum + ;; + esac +} +fake_ip_filter() { + echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m" + echo -e "\033[31m脚本已经内置了大量地址,你只需要添加出现问题的地址!\033[0m" + echo -e "\033[36m示例:a.b.com" + echo -e "示例:*.b.com" + echo -e "示例:*.*.b.com\033[0m" + echo "-----------------------------------------------" + if [ -s ${CRASHDIR}/configs/fake_ip_filter ]; then + echo -e "\033[33m已添加Fake-ip过滤地址:\033[0m" + cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}' + else + echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m" + fi + echo "-----------------------------------------------" + echo -e "\033[32m输入数字直接移除对应地址,输入地址直接添加!\033[0m" + read -p "请输入数字或地址 > " input + case "$input" in + 0) ;; + '') ;; + *) + if [ $input -ge 1 ] 2>/dev/null; then + sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null + echo -e "\033[32m移除成功!\033[0m" + else + echo -e "你输入的地址是:\033[32m$input\033[0m" + read -p "确认添加?(1/0) > " res + [ "$res" = 1 ] && echo $input >>${CRASHDIR}/configs/fake_ip_filter + fi + sleep 1 + fake_ip_filter + ;; + esac +} +set_dns_adv() { #DNS详细设置 + [ -z "$dns_nameserver" ] && dns_nameserver='223.5.5.5, 1.2.4.8' + [ -z "$dns_fallback" ] && dns_fallback="1.1.1.1, 8.8.8.8" + [ -z "$dns_resolver" ] && dns_resolver="223.5.5.5, 2400:3200::1" + [ -z "$hosts_opt" ] && hosts_opt=已启用 + [ -z "$dns_protect" ] && dns_protect=ON + [ -z "$dns_redir" ] && dns_redir=未开启 + [ -z "$dns_no" ] && dns_no=未禁用 + echo "-----------------------------------------------" + echo -e "当前基础DNS:\033[32m$dns_nameserver\033[0m" + echo -e "PROXY-DNS:\033[36m$dns_fallback\033[0m" + echo -e "解析DNS:\033[33m$dns_resolver\033[0m" + echo -e "多个DNS地址请用\033[30;47m“|”\033[0m或者\033[30;47m“, ”\033[0m分隔输入" + echo -e "\033[33m必须拥有本地根证书文件才能使用dot/doh类型的加密dns\033[0m" + echo -e "\033[31m注意singbox内核只有首个dns会被加载!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 修改\033[32m基础DNS\033[0m" + echo -e " 2 修改\033[36mPROXY-DNS\033[0m(该DNS查询会经过节点)" + echo -e " 3 修改\033[33m解析DNS\033[0m(必须是IP,用于解析其他DNS)" + echo -e " 4 DNS防泄漏: \033[36m$dns_protect\033[0m ———启用时少量网站可能连接卡顿" + echo -e " 5 hosts优化: \033[36m$hosts_opt\033[0m ———调用本机hosts并劫持NTP服务" + #echo -e " 6 Dnsmasq转发:\033[36m$dns_redir\033[0m ———不推荐使用" + echo -e " 7 禁用DNS劫持:\033[36m$dns_no\033[0m ———搭配第三方DNS使用" + echo -e " 8 一键配置\033[32m加密DNS\033[0m" + echo -e " 9 \033[33m重置\033[0m默认DNS配置" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + read -p "请输入新的DNS > " dns_nameserver + dns_nameserver=$(echo $dns_nameserver | sed 's#|#\,\ #g') + if [ -n "$dns_nameserver" ]; then + setconfig dns_nameserver "'$dns_nameserver'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + set_dns_adv + ;; + 2) + read -p "请输入新的DNS > " dns_fallback + dns_fallback=$(echo $dns_fallback | sed 's/|/\,\ /g') + if [ -n "$dns_fallback" ]; then + setconfig dns_fallback "'$dns_fallback'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + set_dns_adv + ;; + 3) + read -p "请输入新的DNS > " text + if echo "$text" | grep -qE '://.*::'; then + echo -e "\033[31m此选项暂不支持ipv6加密DNS!!!\033[0m" + elif [ -n "$text" ]; then + dns_resolver=$(echo $text | sed 's/|/\,\ /g') + setconfig dns_resolver "'$dns_resolver'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + set_dns_adv + ;; + 4) + [ "$dns_protect" = "ON" ] && dns_protect=OFF || dns_protect=ON + setconfig dns_protect $dns_protect + set_dns_adv + ;; + 5) + echo "-----------------------------------------------" + if [ "$hosts_opt" = "已启用" ]; then + hosts_opt=未启用 + echo -e "\033[32m已禁用hosts优化功能!!!\033[0m" + else + hosts_opt=已启用 + echo -e "\033[33m已启用hosts优化功能!!!\033[0m" + fi + setconfig hosts_opt $hosts_opt + sleep 1 + set_dns_adv + ;; + 6) + echo "-----------------------------------------------" + if [ "$dns_redir" = "未开启" ]; then + echo -e "\033[31m将使用OpenWrt中Dnsmasq插件自带的DNS转发功能转发DNS请求至内核!\033[0m" + echo -e "\033[33m启用后将禁用本插件自带的iptables转发功能\033[0m" + dns_redir=已开启 + echo -e "\033[32m已启用Dnsmasq转发DNS功能!!!\033[0m" + else + uci del dhcp.@dnsmasq[-1].server + uci set dhcp.@dnsmasq[0].noresolv=0 + uci commit dhcp + /etc/init.d/dnsmasq restart + echo -e "\033[33m禁用成功!!如有报错请重启设备!\033[0m" + dns_redir=未开启 + fi + setconfig dns_redir $dns_redir + sleep 1 + set_dns_adv + ;; + 7) + echo "-----------------------------------------------" + if [ "$dns_no" = "未禁用" ]; then + echo -e "\033[31m仅限搭配其他DNS服务(比如dnsmasq、smartDNS)时使用!\033[0m" + dns_no=已禁用 + echo -e "\033[32m已禁用DNS劫持!!!\033[0m" + else + dns_no=未禁用 + echo -e "\033[33m已启用DNS劫持!!!\033[0m" + fi + setconfig dns_no $dns_no + sleep 1 + set_dns_adv + ;; + 8) + echo "-----------------------------------------------" + openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" + if [ -s "$openssldir/certs/ca-certificates.crt" ] || [ -s "/etc/ssl/certs/ca-certificates.crt" ] || + echo "$crashcore" | grep -qE 'meta|singbox'; then + dns_nameserver='https://dns.alidns.com/dns-query, https://doh.pub/dns-query' + dns_fallback='https://cloudflare-dns.com/dns-query, https://dns.google/dns-query, https://doh.opendns.com/dns-query' + dns_resolver='https://223.5.5.5/dns-query, 2400:3200::1' + setconfig dns_nameserver "'$dns_nameserver'" + setconfig dns_fallback "'$dns_fallback'" + setconfig dns_resolver "'$dns_resolver'" + echo -e "\033[32m已设置加密DNS,如出现DNS解析问题,请尝试重置DNS配置!\033[0m" + else + echo -e "\033[31m找不到根证书文件,无法启用加密DNS,Linux系统请自行搜索安装OpenSSL的方式!\033[0m" + fi + sleep 1 + set_dns_adv + ;; + 9) + dns_nameserver= + dns_fallback= + dns_resolver= + setconfig dns_nameserver + setconfig dns_fallback + setconfig dns_resolver + echo -e "\033[33mDNS配置已重置!!!\033[0m" + sleep 1 + set_dns_adv + ;; + *) + errornum + sleep 1 + ;; + esac +} diff --git a/scripts/menus/gateway.sh b/scripts/menus/gateway.sh index 3c192806..9aa583a0 100644 --- a/scripts/menus/gateway.sh +++ b/scripts/menus/gateway.sh @@ -1,17 +1,14 @@ #!/bin/sh # Copyright (C) Juewuy - -CFG="$CRASHDIR"/configs/gateway.cfg -touch "$CFG" -. "$CFG" +. "$GT_CFG_PATH" gateway(){ #访问与控制主菜单 echo ----------------------------------------------- echo -e "\033[30;47m欢迎使用访问与控制菜单:\033[0m" echo ----------------------------------------------- - echo -e " 1 配置公网访问防火墙" - echo -e " 2 配置Telegram专属控制机器人 \033[32m$bot_tg_service\033[0m" - echo -e " 3 配置DDNS自动域名" + echo -e " 1 配置\033[33m公网访问防火墙\033[0m" + echo -e " 2 配置\033[36mTelegram专属控制机器人\033[0m \033[32m$bot_tg_service\033[0m" + echo -e " 3 配置\033[36mDDNS自动域名\033[0m" [ "$disoverride" != "1" ] && { echo -e " 4 自定义\033[33m公网Vmess入站\033[0m节点 \033[32m$vms_service\033[0m" echo -e " 5 自定义\033[33m公网ShadowSocks入站\033[0m节点 \033[32m$sss_service\033[0m" @@ -32,7 +29,7 @@ gateway(){ #访问与控制主菜单 gateway ;; 3) - set_ddns + . "$CRASHDIR"/menus/ddns.sh && ddns_menu gateway ;; 4) @@ -193,9 +190,6 @@ set_bot_tg(){ ;; esac } -set_ddns(){ - echo 等待施工 -} set_vmess(){ echo ----------------------------------------------- echo -e "\033[31m注意:\033[0m启动内核服务后会自动开放相应端口公网访问,请谨慎使用!\n 脚本只提供基础功能,更多需求请使用自定义配置文件功能!" @@ -224,7 +218,8 @@ set_vmess(){ 2) read -p "请输入端口号(输入0删除) > " text [ "$text" = 0 ] && unset vms_port - if sh "$CRASHDIR"/menus/check_port.sh "$text"; then + . "$CRASHDIR"/menus/check_port.sh + if check_port "$text"; then vms_port="$text" setconfig vms_port "$text" "$CFG" else @@ -293,7 +288,8 @@ set_shadowsocks(){ 2) read -p "请输入端口号(输入0删除) > " text [ "$text" = 0 ] && unset sss_port - if sh "$CRASHDIR"/menus/check_port.sh "$text"; then + . "$CRASHDIR"/menus/check_port.sh + if check_port "$text"; then sss_port="$text" setconfig sss_port "$text" "$CFG" else diff --git a/scripts/menus/normal_set.sh b/scripts/menus/normal_set.sh deleted file mode 100644 index ee3d1a7d..00000000 --- a/scripts/menus/normal_set.sh +++ /dev/null @@ -1,422 +0,0 @@ -#!/bin/sh -# Copyright (C) Juewuy - -normal_set() { #基础设置 - #获取设置默认显示 - [ -z "$skip_cert" ] && skip_cert=已开启 - [ -z "$common_ports" ] && common_ports=已开启 - [ -z "$dns_mod" ] && dns_mod=fake-ip - [ -z "$dns_over" ] && dns_over=已开启 - [ -z "$cn_ip_route" ] && cn_ip_route=未开启 - [ -z "$local_proxy" ] && local_proxy=未开启 - [ -z "$quic_rj" ] && quic_rj=未开启 - [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ] && mac_return=未开启 || mac_return=已启用 - # - echo "-----------------------------------------------" - echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" - echo "-----------------------------------------------" - echo -e " 1 切换防火墙运行模式: \033[36m$redir_mod\033[0m" - [ "$disoverride" != "1" ] && { - echo -e " 2 切换DNS运行模式: \033[36m$dns_mod\033[0m" - echo -e " 3 跳过本地证书验证: \033[36m$skip_cert\033[0m ————解决节点证书验证错误" - } - echo -e " 4 设置流量过滤" - [ "$disoverride" != "1" ] && { - [ "$dns_mod" != "redir_host" ] && - echo -e " 9 管理Fake-ip过滤列表" - } - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单 \033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - if [ "$USER" != "root" -a "$USER" != "admin" ]; then - echo "-----------------------------------------------" - read -p "非root用户可能无法正确配置其他模式!依然尝试吗?(1/0) > " res - [ "$res" = 1 ] && set_redir_mod - else - set_redir_mod - fi - normal_set - ;; - 2) - set_dns_mod - sleep 1 - normal_set - ;; - 4) - set_fw_filter - sleep 1 - normal_set - ;; - 3) - echo "-----------------------------------------------" - if [ "$skip_cert" = "未开启" ] >/dev/null 2>&1; then - echo -e "\033[33m已设为开启跳过本地证书验证!!\033[0m" - skip_cert=已开启 - else - echo -e "\033[33m已设为禁止跳过本地证书验证!!\033[0m" - skip_cert=未开启 - fi - setconfig skip_cert $skip_cert - normal_set - ;; - 9) - echo "-----------------------------------------------" - fake_ip_filter - normal_set - ;; - *) - errornum - ;; - esac -} - -set_fw_filter(){ #流量过滤 - echo "-----------------------------------------------" - echo -e " 1 过滤非常用端口: \033[36m$common_ports\033[0m ————用于过滤P2P流量" - echo -e " 2 过滤局域网设备: \033[36m$mac_return\033[0m ————使用黑/白名单进行过滤" - echo -e " 3 过滤QUIC协议: \033[36m$quic_rj\033[0m ————优化视频性能" - [ "$dns_mod" != "fake-ip" ] && - echo -e " 4 过滤CN_IP(6)列表: \033[36m$cn_ip_route\033[0m ————优化性能,不兼容Fake-ip" - echo -e " 5 自定义透明路由ipv4网段: 适合vlan等复杂网络环境" - echo -e " 6 自定义保留地址ipv4网段: 需要以保留地址为访问目标的环境" - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单 \033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - set_common_ports() { - if [ "$common_ports" = "未开启" ]; then - echo -e "\033[33m当前代理端口为:【$multiport】\033[0m" - echo -e "\033[31m注意,fake-ip模式下,非常用端口的域名连接将不受影响!!\033[0m" - read -p "是否修改默认端口?(1/0) > " res - [ "$res" = "1" ] && { - read -p "请输入自定义端口,注意用小写逗号分隔 > " text - [ -n "$text" ] && setconfig multiport $text && echo -e "\033[33m已设为代理【$multiport】端口!!\033[0m" - } - common_ports=已开启 - sleep 1 - else - echo -e "\033[33m已设为代理全部端口!!\033[0m" - common_ports=未开启 - fi - setconfig common_ports $common_ports - } - echo "-----------------------------------------------" - if [ -n "$(pidof CrashCore)" ]; then - read -p "切换时将停止服务,是否继续?(1/0) > " res - [ "$res" = 1 ] && ${CRASHDIR}/start.sh stop && set_common_ports - else - set_common_ports - fi - set_fw_filter - ;; - 2) - checkcfg_mac=$(cat ${CRASHDIR}/configs/mac) - fw_filter_lan - if [ -n "$PID" ]; then - checkcfg_mac_new=$(cat ${CRASHDIR}/configs/mac) - [ "$checkcfg_mac" != "$checkcfg_mac_new" ] && checkrestart - fi - set_fw_filter - ;; - 3) - echo "-----------------------------------------------" - if [ -n "$(echo "$redir_mod" | grep -oE '混合|Tproxy|Tun')" ]; then - if [ "$quic_rj" = "未开启" ]; then - echo -e "\033[33m已禁止QUIC流量通过ShellCrash内核!!\033[0m" - quic_rj=已启用 - else - echo -e "\033[33m已取消禁止QUIC协议流量!!\033[0m" - quic_rj=未开启 - fi - setconfig quic_rj $quic_rj - else - echo -e "\033[33m当前模式默认不会代理UDP流量,无需设置!!\033[0m" - fi - sleep 1 - set_fw_filter - ;; - 4) - if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = 'nftables' ]; then - if [ "$cn_ip_route" = "未开启" ]; then - echo -e "\033[32m已开启CN_IP绕过内核功能!!\033[0m" - echo -e "\033[31m注意!!!此功能会导致全局模式及一切CN相关规则失效!!!\033[0m" - cn_ip_route=已开启 - sleep 2 - else - echo -e "\033[33m已禁用CN_IP绕过内核功能!!\033[0m" - cn_ip_route=未开启 - fi - setconfig cn_ip_route $cn_ip_route - else - echo -e "\033[31m当前设备缺少ipset模块或未使用nftables模式,无法启用绕过功能!!\033[0m" - sleep 1 - fi - set_fw_filter - ;; - 5) - set_cust_host_ipv4 - set_fw_filter - ;; - 6) - [ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" - echo -e "当前网段:\033[36m$reserve_ipv4\033[0m" - echo -e "\033[33m地址必须是空格分隔,错误的设置可能导致网络回环或启动报错,请务必谨慎!\033[0m" - read -p "请输入 > " text - if [ -n "$( - echo $text | grep -E "(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[1-2]?[0-9]))( +|$)+" - )" ]; then - reserve_ipv4="$text" - echo -e "已将保留地址网段设为:\033[32m$reserve_ipv4\033[0m" - setconfig reserve_ipv4 "'$reserve_ipv4'" - else - echo -e "\033[31m输入有误,操作已取消!\033[0m" - fi - sleep 1 - set_fw_filter - ;; - *) - errornum - ;; - esac -} -set_cust_host_ipv4() { - [ -z "$replace_default_host_ipv4" ] && replace_default_host_ipv4="未启用" - echo "-----------------------------------------------" - echo -e "当前默认透明路由的网段为: \033[32m$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'br' | grep -v 'iot' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ' && echo) \033[0m" - echo -e "当前已添加的自定义网段为:\033[36m$cust_host_ipv4\033[0m" - echo "-----------------------------------------------" - echo -e " 1 移除所有自定义网段" - echo -e " 2 使用自定义网段覆盖默认网段 \033[36m$replace_default_host_ipv4\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应的序号或需要额外添加的网段 > " text - case "$text" in - 2) - if [ "$replace_default_host_ipv4" == "未启用" ]; then - replace_default_host_ipv4="已启用" - else - replace_default_host_ipv4="未启用" - fi - setconfig replace_default_host_ipv4 "$replace_default_host_ipv4" - set_cust_host_ipv4 - ;; - 1) - unset cust_host_ipv4 - setconfig cust_host_ipv4 - set_cust_host_ipv4 - ;; - 0) ;; - *) - if [ -n "$(echo $text | grep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}'$)" -a -z "$(echo $cust_host_ipv4 | grep "$text")" ]; then - cust_host_ipv4="$cust_host_ipv4 $text" - setconfig cust_host_ipv4 "'$cust_host_ipv4'" - else - echo "-----------------------------------------------" - echo -e "\033[31m请输入正确的网段地址!\033[0m" - fi - sleep 1 - set_cust_host_ipv4 - ;; - esac -} -fw_filter_lan() { #局域网设备过滤 - get_devinfo() { - dev_ip=$(cat $dhcpdir | grep " $dev " | awk '{print $3}') && [ -z "$dev_ip" ] && dev_ip=$dev - dev_mac=$(cat $dhcpdir | grep " $dev " | awk '{print $2}') && [ -z "$dev_mac" ] && dev_mac=$dev - dev_name=$(cat $dhcpdir | grep " $dev " | awk '{print $4}') && [ -z "$dev_name" ] && dev_name='未知设备' - } - add_mac() { - echo "-----------------------------------------------" - echo 已添加的mac地址: - cat ${CRASHDIR}/configs/mac 2>/dev/null - echo "-----------------------------------------------" - echo -e "\033[33m序号 设备IP 设备mac地址 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$2,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入mac地址时仅支持\033[32mxx:xx:xx:xx:xx:xx\033[0m的形式" - echo -e " 0 或回车 结束添加" - echo "-----------------------------------------------" - read -p "请输入对应序号或直接输入mac地址 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$num")" ]; then - echo $num | grep -oE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' >>${CRASHDIR}/configs/mac - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - macadd=$(cat $dhcpdir | awk '{print $2}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$macadd")" ]; then - echo $macadd >>${CRASHDIR}/configs/mac - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_mac - fi - } - add_ip() { - echo "-----------------------------------------------" - echo "已添加的IP地址(段):" - cat ${CRASHDIR}/configs/ip_filter 2>/dev/null - echo "-----------------------------------------------" - echo -e "\033[33m序号 设备IP 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入时仅支持\033[32m 192.168.1.0/24\033[0m 或 \033[32m192.168.1.0\033[0m 的形式" - echo -e "不支持ipv6地址过滤,如有需求请使用mac地址过滤" - echo -e " 0 或回车 结束添加" - echo "-----------------------------------------------" - read -p "请输入对应序号或直接输入IP地址段 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/ip_filter | grep -E "$num")" ]; then - echo $num | grep -oE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$' >>${CRASHDIR}/configs/ip_filter - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - ipadd=$(cat $dhcpdir | awk '{print $3}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$ipadd")" ]; then - echo $ipadd >>${CRASHDIR}/configs/ip_filter - else - echo "-----------------------------------------------" - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_ip - fi - } - del_all() { - echo "-----------------------------------------------" - if [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ]; then - echo -e "\033[31m列表中没有需要移除的设备!\033[0m" - sleep 1 - else - echo -e "请选择需要移除的设备:\033[36m" - echo -e "\033[33m 设备IP 设备mac地址 设备名称\033[0m" - i=1 - for dev in $(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e " $i \033[32m$dev_ip \033[36m$dev_mac \033[32m$dev_name\033[0m" - i=$((i + 1)) - done - echo "-----------------------------------------------" - echo -e "\033[0m 0 或回车 结束删除" - read -p "请输入需要移除的设备的对应序号 > " num - mac_filter_rows=$(cat ${CRASHDIR}/configs/mac 2>/dev/null | wc -l) - ip_filter_rows=$(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null | wc -l) - if [ -z "$num" ] || [ "$num" -le 0 ]; then - n= - elif [ $num -le $mac_filter_rows ]; then - sed -i "${num}d" ${CRASHDIR}/configs/mac - echo "-----------------------------------------------" - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - elif [ $num -le $((mac_filter_rows + ip_filter_rows)) ]; then - num=$((num - mac_filter_rows)) - sed -i "${num}d" ${CRASHDIR}/configs/ip_filter - echo "-----------------------------------------------" - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - else - echo "-----------------------------------------------" - echo -e "\033[31m输入有误,请重新输入!\033[0m" - del_all - fi - fi - } - echo "-----------------------------------------------" - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcp/dhcpd.leases ] && dhcpdir='/var/lib/dhcp/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcpd/dhcpd.leases ] && dhcpdir='/var/lib/dhcpd/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dhcp.leases ] && dhcpdir='/tmp/dhcp.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dnsmasq.leases ] && dhcpdir='/tmp/dnsmasq.leases' - [ -z "$dhcpdir" ] && dhcpdir='/dev/null' - [ -z "$fw_filter_lan_type" ] && fw_filter_lan_type='黑名单' - if [ "$fw_filter_lan_type" = "黑名单" ]; then - fw_filter_lan_over='白名单' - fw_filter_lan_scrip='不' - else - fw_filter_lan_over='黑名单' - fw_filter_lan_scrip='' - fi - ###### - echo -e "\033[30;47m请在此添加或移除设备\033[0m" - echo -e "当前过滤方式为:\033[33m$fw_filter_lan_type模式\033[0m" - echo -e "仅列表内设备流量\033[36m$fw_filter_lan_scrip经过\033[0m内核" - if [ -n "$(cat ${CRASHDIR}/configs/mac)" ]; then - echo "-----------------------------------------------" - echo -e "当前已过滤设备为:\033[36m" - echo -e "\033[33m 设备mac/ip地址 设备名称\033[0m" - for dev in $(cat ${CRASHDIR}/configs/mac 2>/dev/null); do - get_devinfo - echo -e "\033[36m$dev_mac \033[0m$dev_name" - done - for dev in $(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e "\033[32m$dev_ip \033[0m$dev_name" - done - echo "-----------------------------------------------" - fi - echo -e " 1 切换为\033[33m$fw_filter_lan_over模式\033[0m" - echo -e " 2 \033[32m添加指定设备(mac地址)\033[0m" - echo -e " 3 \033[32m添加指定设备(IP地址/网段)\033[0m" - echo -e " 4 \033[36m移除指定设备\033[0m" - echo -e " 9 \033[31m清空整个列表\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - fw_filter_lan_type=$fw_filter_lan_over - setconfig fw_filter_lan_type $fw_filter_lan_type - echo "-----------------------------------------------" - echo -e "\033[32m已切换为$fw_filter_lan_type模式!\033[0m" - fw_filter_lan - ;; - 2) - add_mac - fw_filter_lan - ;; - 3) - add_ip - fw_filter_lan - ;; - 4) - del_all - fw_filter_lan - ;; - 9) - : >${CRASHDIR}/configs/mac - : >${CRASHDIR}/configs/ip_filter - echo "-----------------------------------------------" - echo -e "\033[31m设备列表已清空!\033[0m" - fw_filter_lan - ;; - *) - errornum - ;; - esac -} - diff --git a/scripts/menus/setboot.sh b/scripts/menus/setboot.sh new file mode 100644 index 00000000..5b336072 --- /dev/null +++ b/scripts/menus/setboot.sh @@ -0,0 +1,178 @@ +#!/bin/sh +# Copyright (C) Juewuy + +setboot() { #启动设置菜单 + [ -z "$start_old" ] && start_old=未开启 + [ -z "$start_delay" -o "$start_delay" = 0 ] && delay=未设置 || delay=${start_delay}秒 + [ "$autostart" = "enable" ] && auto_set="\033[33m禁止" || auto_set="\033[32m允许" + [ "${BINDIR}" = "${CRASHDIR}" ] && mini_clash=未开启 || mini_clash=已开启 + [ -z "$network_check" ] && network_check=已开启 + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用启动设置菜单:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 ${auto_set}\033[0mShellCrash开机启动" + echo -e " 2 使用保守模式: \033[36m$start_old\033[0m ————基于定时任务(每分钟检测)" + echo -e " 3 设置自启延时: \033[36m$delay\033[0m ————用于解决自启后服务受限" + echo -e " 4 启用小闪存模式: \033[36m$mini_clash\033[0m ————用于闪存空间不足的设备" + [ "${BINDIR}" != "${CRASHDIR}" ] && echo -e " 5 设置小闪存目录: \033[36m${BINDIR}\033[0m" + echo -e " 6 自启网络检查: \033[36m$network_check\033[0m ————禁用则跳过自启时网络检查" + echo "-----------------------------------------------" + echo -e " 0 \033[0m返回上级菜单\033[0m" + read -p "请输入对应数字 > " num + echo "-----------------------------------------------" + case "$num" in + 0) ;; + 1) + if [ "$autostart" = "enable" ]; then + # 禁止自启动:删除各系统的启动项 + [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null + ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 + grep -q 's6' /proc/1/comm && rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/afstart + rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null 2>&1 + touch ${CRASHDIR}/.dis_startup + autostart=disable + echo -e "\033[33m已禁止ShellCrash开机启动!\033[0m" + elif [ "$autostart" = "disable" ]; then + # 允许自启动:配置各系统的启动项 + [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ] && /etc/init.d/shellcrash enable + ckcmd systemctl && systemctl enable shellcrash.service >/dev/null 2>&1 + grep -q 's6' /proc/1/comm && touch /etc/s6-overlay/s6-rc.d/user/contents.d/afstart + rc-status -r >/dev/null 2>&1 && rc-update add shellcrash default >/dev/null 2>&1 + rm -rf ${CRASHDIR}/.dis_startup + autostart=enable + echo -e "\033[32m已设置ShellCrash开机启动!\033[0m" + fi + setboot + ;; + 2) + if [ "$start_old" = "未开启" ] >/dev/null 2>&1; then + echo -e "\033[33m改为使用保守模式启动服务!!\033[0m" + [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null + ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 + grep -q 's6' /proc/1/comm && rm -rf /etc/s6-overlay/s6-rc.d/user/contents.d/afstart + rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null 2>&1 + start_old=已开启 + setconfig start_old $start_old + ${CRASHDIR}/start.sh stop + else + if grep -qE 'procd|systemd|s6' /proc/1/comm || rc-status -r >/dev/null 2>&1; then + echo -e "\033[32m改为使用系统守护进程启动服务!!\033[0m" + ${CRASHDIR}/start.sh cronset "ShellCrash初始化" + start_old=未开启 + setconfig start_old $start_old + ${CRASHDIR}/start.sh stop + + else + echo -e "\033[31m当前设备不支持以其他模式启动!!\033[0m" + fi + fi + sleep 1 + setboot + ;; + 3) + echo -e "\033[33m如果你的设备启动后可以正常使用,则无需设置!!\033[0m" + echo -e "\033[36m推荐设置为30~120秒之间,请根据设备问题自行试验\033[0m" + read -p "请输入启动延迟时间(0~300秒) > " sec + case "$sec" in + [0-9] | [0-9][0-9] | [0-2][0-9][0-9] | 300) + start_delay=$sec + setconfig start_delay $sec + echo -e "\033[32m设置成功!\033[0m" + ;; + *) + echo -e "\033[31m输入有误,或超过300秒,请重新输入!\033[0m" + ;; + esac + sleep 1 + setboot + ;; + 4) + dir_size=$(df ${CRASHDIR} | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | grep Ava | awk '{print $2}') + if [ "$mini_clash" = "未开启" ]; then + if [ "$dir_size" -gt 20480 ]; then + echo -e "\033[33m您的设备空间充足(>20M),无需开启!\033[0m" + elif [ "$start_old" != '已开启' -a "$(cat /proc/1/comm)" = "systemd" ]; then + echo -e "\033[33m不支持systemd启动模式,请先启用保守模式!\033[0m" + else + [ "$BINDIR" = "$CRASHDIR" ] && BINDIR="$TMPDIR" + echo -e "\033[32m已经启用小闪存功能!\033[0m" + echo -e "如需更换目录,请使用【设置小闪存目录】功能\033[0m" + fi + else + if [ "$dir_size" -lt 8192 ]; then + echo -e "\033[31m您的设备剩余空间不足8M,停用后可能无法正常运行!\033[0m" + read -p "确认停用此功能?(1/0) > " res + [ "$res" = 1 ] && BINDIR="$CRASHDIR" && echo -e "\033[33m已经停用小闪存功能!\033[0m" + else + rm -rf /tmp/ShellCrash + BINDIR="$CRASHDIR" + echo -e "\033[33m已经停用小闪存功能!\033[0m" + fi + fi + setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env + sleep 1 + setboot + ;; + 5) + echo -e "\033[33m如设置到内存,则每次开机后都自动重新下载相关文件\033[0m" + echo -e "\033[33m请确保安装源可用裸连,否则会导致启动失败\033[0m" + echo " 1 使用内存(/tmp)" + echo " 2 选择U盘目录" + echo " 3 自定义目录" + read -p "请输入相应数字 > " num + case "$num" in + 1) + BINDIR="$TMPDIR" + ;; + 2) + set_usb_dir() { + echo "请选择安装目录" + du -hL /mnt | awk '{print " "NR" "$2" "$1}' + read -p "请输入相应数字 > " num + BINDIR=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) + if [ -z "$BINDIR" ]; then + echo "\033[31m输入错误!请重新设置!\033[0m" + set_usb_dir + fi + } + set_usb_dir + ;; + 3) + input_dir() { + read -p "请输入自定义目录 > " BINDIR + if [ ! -d "$BINDIR" ]; then + echo "\033[31m输入错误!请重新设置!\033[0m" + input_dir + fi + } + input_dir + ;; + *) + errornum + ;; + esac + setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env + setboot + ;; + 6) + echo -e "\033[33m如果你的设备启动后可以正常使用,则无需变更设置!!\033[0m" + echo -e "\033[36m禁用时,如果使用了小闪存模式或者rule-set等在线规则,则可能会因无法联网而导致启动失败!\033[0m" + echo -e "\033[32m启用时,会导致部分性能较差或者拨号较慢的设备可能会因查询超时导致启动失败!\033[0m" + read -p "是否切换?(1/0) > " res + [ "$res" = '1' ] && { + if [ "$network_check" = "已禁用" ]; then + network_check=已启用 + else + network_check=已禁用 + fi + setconfig network_check $network_check + } + sleep 1 + setboot + ;; + *) + errornum + ;; + esac + +} diff --git a/scripts/menus/settings.sh b/scripts/menus/settings.sh new file mode 100644 index 00000000..7f83ca33 --- /dev/null +++ b/scripts/menus/settings.sh @@ -0,0 +1,971 @@ +#!/bin/sh +# Copyright (C) Juewuy + +settings() { #功能设置 + #获取设置默认显示 + [ -z "$skip_cert" ] && skip_cert=已开启 + [ -z "$sniffer" ] && sniffer=未启用 + # + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 设置代理模式: \033[36m$redir_mod\033[0m" + echo -e " 2 设置DNS模式: \033[36m$dns_mod\033[0m" + echo -e " 3 设置各类流量过滤" + [ "$disoverride" != "1" ] && { + echo -e " 4 跳过证书验证: \033[36m$skip_cert\033[0m" + echo -e " 5 启用域名嗅探: \033[36m$sniffer\033[0m" + echo -e " 6 自定义\033[32m端口及秘钥\033[0m" + } + echo -e " 8 ipv6设置: \033[36m$ipv6_redir\033[0m" + echo "-----------------------------------------------" + echo -e " 9 \033[31m重置/备份/还原\033[0m脚本设置" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + if [ "$USER" != "root" -a "$USER" != "admin" ]; then + echo "-----------------------------------------------" + read -p "非root用户可能无法正确配置其他模式!依然尝试吗?(1/0) > " res + [ "$res" = 1 ] && set_redir_mod + else + set_redir_mod + fi + sleep 1 + settings + ;; + 2) + set_dns_mod + sleep 1 + settings + ;; + 3) + set_fw_filter + sleep 1 + settings + ;; + 4) + echo "-----------------------------------------------" + if [ "$skip_cert" = "未开启" ] >/dev/null 2>&1; then + echo -e "\033[33m已设为开启跳过本地证书验证!!\033[0m" + skip_cert=已开启 + else + echo -e "\033[33m已设为禁止跳过本地证书验证!!\033[0m" + skip_cert=未开启 + fi + setconfig skip_cert $skip_cert + settings + ;; + 5) + echo "-----------------------------------------------" + if [ "$sniffer" = "未启用" ]; then + if [ "$crashcore" = "clash" ]; then + rm -rf ${TMPDIR}/CrashCore + rm -rf ${CRASHDIR}/CrashCore + rm -rf ${CRASHDIR}/CrashCore.tar.gz + crashcore=meta + setconfig crashcore $crashcore + echo "已将ShellCrash内核切换为Meta内核!域名嗅探依赖Meta或者高版本clashpre内核!" + fi + sniffer=已启用 + elif [ "$crashcore" = "clashpre" -a "$dns_mod" = "redir_host" ]; then + echo -e "\033[31m使用clashpre内核且开启redir-host模式时无法关闭!\033[0m" + else + sniffer=未启用 + fi + setconfig sniffer $sniffer + settings + ;; + 6) + if [ -n "$(pidof CrashCore)" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" + read -p "是否停止服务?(1/0) > " res + if [ "$res" = "1" ]; then + ${CRASHDIR}/start.sh stop + set_adv_config + fi + else + set_adv_config + fi + settings + ;; + 8) + set_ipv6 + settings + ;; + 9) + echo "-----------------------------------------------" + echo -e " 1 备份脚本设置" + echo -e " 2 还原脚本设置" + echo -e " 3 重置脚本设置" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + errornum + elif [ "$num" = 0 ]; then + i= + elif [ "$num" = 1 ]; then + cp -f "$CFG_PATH" "$CFG_PATH".bak + echo -e "\033[32m脚本设置已备份!\033[0m" + elif [ "$num" = 2 ]; then + if [ -f "$CFG_PATH.bak" ]; then + mv -f "$CFG_PATH" "$CFG_PATH".bak2 + mv -f "$CFG_PATH".bak "$CFG_PATH" + mv -f "$CFG_PATH".bak2 "$CFG_PATH".bak + echo -e "\033[32m脚本设置已还原!(被覆盖的配置已备份!)\033[0m" + else + echo -e "\033[31m找不到备份文件,请先备份脚本设置!\033[0m" + fi + elif [ "$num" = 3 ]; then + mv -f "$CFG_PATH" "$CFG_PATH".bak + . ${CRASHDIR}/init.sh >/dev/null + echo -e "\033[32m脚本设置已重置!(旧文件已备份!)\033[0m" + fi + echo -e "\033[33m请重新启动脚本!\033[0m" + exit 0 + ;; + *) + errornum + ;; + esac +} + +set_redir_mod() { #代理模式设置 + set_redir_config() { + setconfig redir_mod $redir_mod + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $redir_mod !!\033[0m" + } + [ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1 + [ -z "$firewall_area" ] && firewall_area=1 + [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' + [ -z "$redir_mod" ] && redir_mod='纯净模式' + firewall_area_dsc=$(echo "仅局域网 仅本机 局域网+本机 纯净模式 主-旁转发($bypass_host)" | cut -d' ' -f$firewall_area) + echo "-----------------------------------------------" + echo -e "当前代理模式为:\033[47;30m$redir_mod\033[0m;ShellCrash核心为:\033[47;30m $crashcore \033[0m" + echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" + echo "-----------------------------------------------" + [ $firewall_area -le 3 ] && { + echo -e " 1 \033[32mRedir模式\033[0m: Redir转发TCP,不转发UDP" + echo -e " 2 \033[36m混合模式\033[0m: Redir转发TCP,Tun转发UDP" + echo -e " 3 \033[32mTproxy模式\033[0m: Tproxy转发TCP&UDP" + echo -e " 4 \033[33mTun模式\033[0m: Tun转发TCP&UDP(占用高不推荐)" + echo "-----------------------------------------------" + } + [ "$firewall_area" = 5 ] && { + echo -e " 5 \033[32mTCP旁路转发\033[0m: 仅转发TCP流量至旁路由" + echo -e " 6 \033[36mT&U旁路转发\033[0m: 转发TCP&UDP流量至旁路由" + echo "-----------------------------------------------" + } + echo -e " 7 设置代理范围: \033[47;30m$firewall_area_dsc\033[0m" + echo -e " 8 容器/虚拟机代理: \033[47;30m$vm_redir\033[0m" + echo -e " 9 切换防火墙应用: \033[47;30m$firewall_mod\033[0m" + echo "-----------------------------------------------" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + redir_mod=Redir模式 + set_redir_config + set_redir_mod + ;; + 2) + if [ -n "$sup_tun" ]; then + redir_mod=混合模式 + set_redir_config + else + echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + set_redir_mod + ;; + 3) + if [ "$firewall_mod" = "iptables" ]; then + if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ]; then + read -p "xiaomi设备的QOS服务与本模式冲突,是否禁用相关功能?(1/0) > " res + [ "$res" = '1' ] && { + ${CRASHDIR}/misnap_init.sh tproxyfix + redir_mod=Tproxy模式 + set_redir_config + } + elif grep -qE '^TPROXY$' /proc/net/ip_tables_targets || modprobe xt_TPROXY >/dev/null 2>&1; then + redir_mod=Tproxy模式 + set_redir_config + else + echo -e "\033[31m设备未检测到iptables-mod-tproxy模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + elif [ "$firewall_mod" = "nftables" ]; then + if modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy; then + redir_mod=Tproxy模式 + set_redir_config + else + echo -e "\033[31m设备未检测到nft_tproxy内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + fi + set_redir_mod + ;; + 4) + if [ -n "$sup_tun" ]; then + redir_mod=Tun模式 + set_redir_config + else + echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + set_redir_mod + ;; + 5) + redir_mod=TCP旁路转发 + set_redir_config + set_redir_mod + ;; + 6) + redir_mod=T & + U旁路转发 + set_redir_config + set_redir_mod + ;; + 7) + set_firewall_area + set_redir_mod + ;; + 8) + set_firewall_vm + set_redir_mod + ;; + 9) + if [ "$firewall_mod" = 'iptables' ]; then + if nft add table inet shellcrash 2>/dev/null; then + firewall_mod=nftables + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + else + echo -e "\033[31m当前设备未安装nftables或者nftables版本过低(<1.0.2),无法切换!\033[0m" + fi + elif [ "$firewall_mod" = 'nftables' ]; then + if ckcmd iptables; then + firewall_mod=iptables + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + else + echo -e "\033[31m当前设备未安装iptables,无法切换!\033[0m" + fi + else + iptables -j REDIRECT -h >/dev/null 2>&1 && firewall_mod=iptables + nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables + if [ -n "$firewall_mod" ]; then + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + setconfig firewall_mod $firewall_mod + else + echo -e "\033[31m检测不到可用的防火墙应用(iptables/nftables),无法切换!\033[0m" + fi + fi + sleep 1 + setconfig firewall_mod $firewall_mod + set_redir_mod + ;; + *) + errornum + ;; + esac +} +set_dns_mod() { #DNS模式设置 + echo "-----------------------------------------------" + echo -e "当前DNS运行模式为:\033[47;30m $dns_mod \033[0m" + echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 fake-ip模式: 响应快,\033[33m兼容性较差\033[0m" + echo -e " 不支持CN-IP绕过功能" + echo -e " 2 redir_host模式:\033[33m不安全,易被污染\033[0m" + echo -e " 建议搭配第三方DNS服务使用" + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + echo -e " 3 mix混合模式: \033[32m防污染防泄露,响应快,推荐!\033[0m" + echo -e " cn域名realip其他fakeip分流" + echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" + echo -e " cn域名realip其他dns2proxy分流" + fi + echo -e " 9 \033[36mDNS进阶设置\033[0m" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + dns_mod=fake-ip + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + ;; + 2) + dns_mod=redir_host + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + ;; + 3) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=mix + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + ;; + 4) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=route + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + ;; + 9) + setdns + set_dns_mod + ;; + *) + errornum + ;; + esac +} +set_fw_filter(){ #流量过滤 + [ -z "$common_ports" ] && common_ports=已开启 + [ -z "$quic_rj" ] && quic_rj=未开启 + [ -z "$cn_ip_route" ] && cn_ip_route=未开启 + [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ] && mac_return=未开启 || mac_return=已启用 + echo "-----------------------------------------------" + echo -e " 1 过滤非常用端口: \033[36m$common_ports\033[0m ————用于过滤P2P流量" + echo -e " 2 过滤局域网设备: \033[36m$mac_return\033[0m ————使用黑/白名单进行过滤" + echo -e " 3 过滤QUIC协议: \033[36m$quic_rj\033[0m ————优化视频性能" + [ "$dns_mod" != "fake-ip" ] && + echo -e " 4 过滤CN_IP(6)列表: \033[36m$cn_ip_route\033[0m ————优化性能,不兼容Fake-ip" + echo -e " 5 自定义透明路由ipv4网段: 适合vlan等复杂网络环境" + echo -e " 6 自定义保留地址ipv4网段: 需要以保留地址为访问目标的环境" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + set_common_ports() { + if [ "$common_ports" = "未开启" ]; then + echo -e "\033[33m当前代理端口为:【$multiport】\033[0m" + echo -e "\033[31m注意,fake-ip模式下,非常用端口的域名连接将不受影响!!\033[0m" + read -p "是否修改默认端口?(1/0) > " res + [ "$res" = "1" ] && { + read -p "请输入自定义端口,注意用小写逗号分隔 > " text + [ -n "$text" ] && setconfig multiport $text && echo -e "\033[33m已设为代理【$multiport】端口!!\033[0m" + } + common_ports=已开启 + sleep 1 + else + echo -e "\033[33m已设为代理全部端口!!\033[0m" + common_ports=未开启 + fi + setconfig common_ports $common_ports + } + echo "-----------------------------------------------" + if [ -n "$(pidof CrashCore)" ]; then + read -p "切换时将停止服务,是否继续?(1/0) > " res + [ "$res" = 1 ] && ${CRASHDIR}/start.sh stop && set_common_ports + else + set_common_ports + fi + set_fw_filter + ;; + 2) + checkcfg_mac=$(cat ${CRASHDIR}/configs/mac) + fw_filter_lan + if [ -n "$PID" ]; then + checkcfg_mac_new=$(cat ${CRASHDIR}/configs/mac) + [ "$checkcfg_mac" != "$checkcfg_mac_new" ] && checkrestart + fi + set_fw_filter + ;; + 3) + echo "-----------------------------------------------" + if [ -n "$(echo "$redir_mod" | grep -oE '混合|Tproxy|Tun')" ]; then + if [ "$quic_rj" = "未开启" ]; then + echo -e "\033[33m已禁止QUIC流量通过ShellCrash内核!!\033[0m" + quic_rj=已启用 + else + echo -e "\033[33m已取消禁止QUIC协议流量!!\033[0m" + quic_rj=未开启 + fi + setconfig quic_rj $quic_rj + else + echo -e "\033[33m当前模式默认不会代理UDP流量,无需设置!!\033[0m" + fi + sleep 1 + set_fw_filter + ;; + 4) + if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = 'nftables' ]; then + if [ "$cn_ip_route" = "未开启" ]; then + echo -e "\033[32m已开启CN_IP绕过内核功能!!\033[0m" + echo -e "\033[31m注意!!!此功能会导致全局模式及一切CN相关规则失效!!!\033[0m" + cn_ip_route=已开启 + sleep 2 + else + echo -e "\033[33m已禁用CN_IP绕过内核功能!!\033[0m" + cn_ip_route=未开启 + fi + setconfig cn_ip_route $cn_ip_route + else + echo -e "\033[31m当前设备缺少ipset模块或未使用nftables模式,无法启用绕过功能!!\033[0m" + sleep 1 + fi + set_fw_filter + ;; + 5) + set_cust_host_ipv4 + set_fw_filter + ;; + 6) + [ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" + echo -e "当前网段:\033[36m$reserve_ipv4\033[0m" + echo -e "\033[33m地址必须是空格分隔,错误的设置可能导致网络回环或启动报错,请务必谨慎!\033[0m" + read -p "请输入 > " text + if [ -n "$( + echo $text | grep -E "(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[1-2]?[0-9]))( +|$)+" + )" ]; then + reserve_ipv4="$text" + echo -e "已将保留地址网段设为:\033[32m$reserve_ipv4\033[0m" + setconfig reserve_ipv4 "'$reserve_ipv4'" + else + echo -e "\033[31m输入有误,操作已取消!\033[0m" + fi + sleep 1 + set_fw_filter + ;; + *) + errornum + ;; + esac +} + +set_cust_host_ipv4() { #自定义ipv4透明路由网段 + [ -z "$replace_default_host_ipv4" ] && replace_default_host_ipv4="未启用" + echo "-----------------------------------------------" + echo -e "当前默认透明路由的网段为: \033[32m$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'br' | grep -v 'iot' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ' && echo) \033[0m" + echo -e "当前已添加的自定义网段为:\033[36m$cust_host_ipv4\033[0m" + echo "-----------------------------------------------" + echo -e " 1 移除所有自定义网段" + echo -e " 2 使用自定义网段覆盖默认网段 \033[36m$replace_default_host_ipv4\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应的序号或需要额外添加的网段 > " text + case "$text" in + 2) + if [ "$replace_default_host_ipv4" == "未启用" ]; then + replace_default_host_ipv4="已启用" + else + replace_default_host_ipv4="未启用" + fi + setconfig replace_default_host_ipv4 "$replace_default_host_ipv4" + set_cust_host_ipv4 + ;; + 1) + unset cust_host_ipv4 + setconfig cust_host_ipv4 + set_cust_host_ipv4 + ;; + 0) ;; + *) + if [ -n "$(echo $text | grep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}'$)" -a -z "$(echo $cust_host_ipv4 | grep "$text")" ]; then + cust_host_ipv4="$cust_host_ipv4 $text" + setconfig cust_host_ipv4 "'$cust_host_ipv4'" + else + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的网段地址!\033[0m" + fi + sleep 1 + set_cust_host_ipv4 + ;; + esac +} +fw_filter_lan() { #局域网设备过滤 + get_devinfo() { + dev_ip=$(cat $dhcpdir | grep " $dev " | awk '{print $3}') && [ -z "$dev_ip" ] && dev_ip=$dev + dev_mac=$(cat $dhcpdir | grep " $dev " | awk '{print $2}') && [ -z "$dev_mac" ] && dev_mac=$dev + dev_name=$(cat $dhcpdir | grep " $dev " | awk '{print $4}') && [ -z "$dev_name" ] && dev_name='未知设备' + } + add_mac() { + echo "-----------------------------------------------" + echo 已添加的mac地址: + cat ${CRASHDIR}/configs/mac 2>/dev/null + echo "-----------------------------------------------" + echo -e "\033[33m序号 设备IP 设备mac地址 设备名称\033[32m" + cat $dhcpdir | awk '{print " "NR" "$3,$2,$4}' + echo -e "\033[0m-----------------------------------------------" + echo -e "手动输入mac地址时仅支持\033[32mxx:xx:xx:xx:xx:xx\033[0m的形式" + echo -e " 0 或回车 结束添加" + echo "-----------------------------------------------" + read -p "请输入对应序号或直接输入mac地址 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ -n "$(echo $num | grep -aE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$')" ]; then + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$num")" ]; then + echo $num | grep -oE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' >>${CRASHDIR}/configs/mac + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" + fi + add_mac + elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then + macadd=$(cat $dhcpdir | awk '{print $2}' | sed -n "$num"p) + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$macadd")" ]; then + echo $macadd >>${CRASHDIR}/configs/mac + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" + fi + add_mac + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + add_mac + fi + } + add_ip() { + echo "-----------------------------------------------" + echo "已添加的IP地址(段):" + cat ${CRASHDIR}/configs/ip_filter 2>/dev/null + echo "-----------------------------------------------" + echo -e "\033[33m序号 设备IP 设备名称\033[32m" + cat $dhcpdir | awk '{print " "NR" "$3,$4}' + echo -e "\033[0m-----------------------------------------------" + echo -e "手动输入时仅支持\033[32m 192.168.1.0/24\033[0m 或 \033[32m192.168.1.0\033[0m 的形式" + echo -e "不支持ipv6地址过滤,如有需求请使用mac地址过滤" + echo -e " 0 或回车 结束添加" + echo "-----------------------------------------------" + read -p "请输入对应序号或直接输入IP地址段 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ -n "$(echo $num | grep -aE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$')" ]; then + if [ -z "$(cat ${CRASHDIR}/configs/ip_filter | grep -E "$num")" ]; then + echo $num | grep -oE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$' >>${CRASHDIR}/configs/ip_filter + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" + fi + add_ip + elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then + ipadd=$(cat $dhcpdir | awk '{print $3}' | sed -n "$num"p) + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$ipadd")" ]; then + echo $ipadd >>${CRASHDIR}/configs/ip_filter + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" + fi + add_ip + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + add_ip + fi + } + del_all() { + echo "-----------------------------------------------" + if [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ]; then + echo -e "\033[31m列表中没有需要移除的设备!\033[0m" + sleep 1 + else + echo -e "请选择需要移除的设备:\033[36m" + echo -e "\033[33m 设备IP 设备mac地址 设备名称\033[0m" + i=1 + for dev in $(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null); do + get_devinfo + echo -e " $i \033[32m$dev_ip \033[36m$dev_mac \033[32m$dev_name\033[0m" + i=$((i + 1)) + done + echo "-----------------------------------------------" + echo -e "\033[0m 0 或回车 结束删除" + read -p "请输入需要移除的设备的对应序号 > " num + mac_filter_rows=$(cat ${CRASHDIR}/configs/mac 2>/dev/null | wc -l) + ip_filter_rows=$(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null | wc -l) + if [ -z "$num" ] || [ "$num" -le 0 ]; then + n= + elif [ $num -le $mac_filter_rows ]; then + sed -i "${num}d" ${CRASHDIR}/configs/mac + echo "-----------------------------------------------" + echo -e "\033[32m对应设备已移除!\033[0m" + del_all + elif [ $num -le $((mac_filter_rows + ip_filter_rows)) ]; then + num=$((num - mac_filter_rows)) + sed -i "${num}d" ${CRASHDIR}/configs/ip_filter + echo "-----------------------------------------------" + echo -e "\033[32m对应设备已移除!\033[0m" + del_all + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + del_all + fi + fi + } + echo "-----------------------------------------------" + [ -z "$dhcpdir" ] && [ -f /var/lib/dhcp/dhcpd.leases ] && dhcpdir='/var/lib/dhcp/dhcpd.leases' + [ -z "$dhcpdir" ] && [ -f /var/lib/dhcpd/dhcpd.leases ] && dhcpdir='/var/lib/dhcpd/dhcpd.leases' + [ -z "$dhcpdir" ] && [ -f /tmp/dhcp.leases ] && dhcpdir='/tmp/dhcp.leases' + [ -z "$dhcpdir" ] && [ -f /tmp/dnsmasq.leases ] && dhcpdir='/tmp/dnsmasq.leases' + [ -z "$dhcpdir" ] && dhcpdir='/dev/null' + [ -z "$fw_filter_lan_type" ] && fw_filter_lan_type='黑名单' + if [ "$fw_filter_lan_type" = "黑名单" ]; then + fw_filter_lan_over='白名单' + fw_filter_lan_scrip='不' + else + fw_filter_lan_over='黑名单' + fw_filter_lan_scrip='' + fi + ###### + echo -e "\033[30;47m请在此添加或移除设备\033[0m" + echo -e "当前过滤方式为:\033[33m$fw_filter_lan_type模式\033[0m" + echo -e "仅列表内设备流量\033[36m$fw_filter_lan_scrip经过\033[0m内核" + if [ -n "$(cat ${CRASHDIR}/configs/mac)" ]; then + echo "-----------------------------------------------" + echo -e "当前已过滤设备为:\033[36m" + echo -e "\033[33m 设备mac/ip地址 设备名称\033[0m" + for dev in $(cat ${CRASHDIR}/configs/mac 2>/dev/null); do + get_devinfo + echo -e "\033[36m$dev_mac \033[0m$dev_name" + done + for dev in $(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null); do + get_devinfo + echo -e "\033[32m$dev_ip \033[0m$dev_name" + done + echo "-----------------------------------------------" + fi + echo -e " 1 切换为\033[33m$fw_filter_lan_over模式\033[0m" + echo -e " 2 \033[32m添加指定设备(mac地址)\033[0m" + echo -e " 3 \033[32m添加指定设备(IP地址/网段)\033[0m" + echo -e " 4 \033[36m移除指定设备\033[0m" + echo -e " 9 \033[31m清空整个列表\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + fw_filter_lan_type=$fw_filter_lan_over + setconfig fw_filter_lan_type $fw_filter_lan_type + echo "-----------------------------------------------" + echo -e "\033[32m已切换为$fw_filter_lan_type模式!\033[0m" + fw_filter_lan + ;; + 2) + add_mac + fw_filter_lan + ;; + 3) + add_ip + fw_filter_lan + ;; + 4) + del_all + fw_filter_lan + ;; + 9) + : >${CRASHDIR}/configs/mac + : >${CRASHDIR}/configs/ip_filter + echo "-----------------------------------------------" + echo -e "\033[31m设备列表已清空!\033[0m" + fw_filter_lan + ;; + *) + errornum + ;; + esac +} +set_adv_config() { #端口设置 + . "$CFG_PATH" >/dev/null + [ -z "$secret" ] && secret=未设置 + [ -z "$table" ] && table=100 + [ -z "$authentication" ] && auth=未设置 || auth=****** + inputport() { + read -p "请输入端口号(1-65535) > " portx + . "$CRASHDIR"/menus/check_port.sh #加载测试函数 + if check_port "$portx"; then + setconfig "$xport" "$portx" + echo -e "\033[32m设置成功!!!\033[0m" + set_adv_config + else + sleep 1 + fi + } + echo "-----------------------------------------------" + echo -e " 1 修改Http/Sock5端口: \033[36m$mix_port\033[0m" + echo -e " 2 设置Http/Sock5密码: \033[36m$auth\033[0m" + echo -e " 3 修改Redir/Tproxy端口:\033[36m$redir_port,$((redir_port + 1))\033[0m" + echo -e " 4 修改DNS监听端口: \033[36m$dns_port\033[0m" + echo -e " 5 修改面板访问端口: \033[36m$db_port\033[0m" + echo -e " 6 设置面板访问密码: \033[36m$secret\033[0m" + echo -e " 7 修改默认端口过滤: \033[36m$multiport\033[0m" + echo -e " 8 自定义本机host地址: \033[36m$host\033[0m" + echo -e " 9 自定义路由表: \033[36m$table,$((table + 1))\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + xport=mix_port + inputport + ;; + 2) + echo "-----------------------------------------------" + echo -e "格式必须是\033[32m 用户名:密码 \033[0m的形式,注意用小写冒号分隔!" + echo -e "请尽量不要使用特殊符号!避免产生未知错误!" + echo "输入 0 删除密码" + echo "-----------------------------------------------" + read -p "请输入Http/Sock5用户名及密码 > " input + if [ "$input" = "0" ]; then + authentication="" + setconfig authentication + echo 密码已移除! + else + if [ "$local_proxy" = "已开启" -a "$local_type" = "环境变量" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m请先禁用本机代理功能或使用增强模式!\033[0m" + sleep 1 + else + authentication=$(echo $input | grep :) + if [ -n "$authentication" ]; then + setconfig authentication "'$authentication'" + echo -e "\033[32m设置成功!!!\033[0m" + else + echo -e "\033[31m输入有误,请重新输入!\033[0m" + fi + fi + fi + set_adv_config + ;; + 3) + xport=redir_port + inputport + ;; + 4) + xport=dns_port + inputport + ;; + 5) + xport=db_port + inputport + ;; + 6) + read -p "请输入面板访问密码(输入0删除密码) > " secret + if [ -n "$secret" ]; then + [ "$secret" = "0" ] && secret="" + setconfig secret $secret + echo -e "\033[32m设置成功!!!\033[0m" + fi + set_adv_config + ;; + 7) + echo "-----------------------------------------------" + echo -e "需配合\033[32m仅代理常用端口\033[0m功能使用" + echo -e "多个端口请用小写逗号分隔,例如:\033[33m143,80,443\033[0m" + echo -e "输入 0 重置为默认端口" + echo "-----------------------------------------------" + read -p "请输入需要指定代理的端口 > " multiport + if [ -n "$multiport" ]; then + [ "$multiport" = "0" ] && multiport="22,80,143,194,443,465,587,853,993,995,5222,8080,8443" + common_ports=已开启 + setconfig multiport "$multiport" + setconfig common_ports "$common_ports" + echo -e "\033[32m设置成功!!!\033[0m" + fi + set_adv_config + ;; + 8) + echo "-----------------------------------------------" + echo -e "\033[33m如果你的局域网网段不是192.168.x或172.16.x或10.x开头,请务必修改!\033[0m" + echo -e "\033[31m设置后如本机host地址有变动,请务必重新修改!\033[0m" + echo "-----------------------------------------------" + read -p "请输入自定义host地址(输入0移除自定义host) > " host + if [ "$host" = "0" ]; then + host="" + setconfig host "$host" + echo -e "\033[32m已经移除自定义host地址,请重新运行脚本以自动获取host!!!\033[0m" + exit 0 + elif [ -n "$(echo $host | grep -E -o '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>){2}\.\<([1-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>')" ]; then + setconfig host "$host" + echo -e "\033[32m设置成功!!!\033[0m" + else + host="" + echo -e "\033[31m输入错误,请仔细核对!!!\033[0m" + fi + sleep 1 + set_adv_config + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[33m仅限Tproxy、Tun或混合模式路由表出现冲突时才需要设置!\033[0m" + read -p "请输入路由表地址(不明勿动!建议102-125之间) > " table + if [ -n "$table" ]; then + [ "$table" = "0" ] && table="100" + setconfig table "$table" + echo -e "\033[32m设置成功!!!\033[0m" + fi + set_adv_config + ;; + *) + errornum + ;; + esac +} +set_firewall_area() { #代理范围设置 + [ -z "$vm_redir" ] && vm_redir='未开启' + echo "-----------------------------------------------" + echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6!" + echo -e "\033[33m如你使用了第三方DNS如smartdns等,请勿启用本机代理或使用shellcrash用户执行!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[32m仅代理局域网流量\033[0m" + echo -e " 2 \033[36m仅代理本机流量\033[0m" + echo -e " 3 \033[32m代理局域网+本机流量\033[0m" + echo -e " 4 不配置流量代理(纯净模式)\033[0m" + #echo -e " 5 \033[33m转发局域网流量到旁路由设备\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + [1-4]) + [ $firewall_area -ge 4 ] && { + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + } + [ "$num" = 4 ] && { + redir_mod=纯净模式 + setconfig redir_mod $redir_mod + } + firewall_area=$num + setconfig firewall_area $firewall_area + ;; + 5) + echo "-----------------------------------------------" + echo -e "\033[31m注意:\033[0m此功能存在多种风险如无网络基础请勿尝试!" + echo -e "\033[33m说明:\033[0m此功能不启动内核仅配置防火墙转发,且子设备无需额外设置网关DNS" + echo -e "\033[33m说明:\033[0m支持防火墙分流及设备过滤,支持部分定时任务,但不支持ipv6!" + echo -e "\033[31m注意:\033[0m如需代理UDP,请确保旁路由运行了支持UDP代理的模式!" + echo -e "\033[31m注意:\033[0m如使用systemd方式启动,内核依然会空载运行,建议使用保守模式!" + echo "-----------------------------------------------" + read -p "请输入旁路由IPV4地址 > " bypass_host + [ -n "$bypass_host" ] && { + firewall_area=$num + setconfig firewall_area $firewall_area + setconfig bypass_host $bypass_host + redir_mod=TCP旁路转发 + setconfig redir_mod $redir_mod + } + ;; + *) errornum ;; + esac + sleep 1 +} +set_firewall_vm(){ + if [ -n "$vm_ipv4" ]; then + vm_des='当前代理' + else + vm_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -E 'docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | sed 's/.*inet.//g' | sed 's/ br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ') + vm_des='当前获取到' + fi + echo "-----------------------------------------------" + echo -e "$vm_des的容器/虚拟机网段为:\033[32m$vm_ipv4\033[0m" + echo -e "如未包含容器网段,请先运行容器再运行脚本或者手动设置网段" + echo "-----------------------------------------------" + echo -e " 1 \033[32m启用代理并使用默认网段\033[0m" + echo -e " 2 \033[36m启用代理并自定义网段\033[0m" + echo -e " 3 \033[31m禁用代理\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 1) + if [ -n "$vm_ipv4" ]; then + vm_redir=已开启 + else + echo -e "\033[33m请先运行容器再运行脚本或者手动设置网段\033[0m" + fi + ;; + 2) + echo -e "多个网段请用空格连接,可运行容器后使用【ip route】命令查看网段地址" + echo -e "示例:\033[32m10.88.0.0/16 172.17.0.0/16\033[0m" + read -p "请输入自定义网段 > " text + [ -n "$text" ] && vm_ipv4=$text && vm_redir=已开启 + ;; + 3) + vm_redir=未开启 + unset vm_ipv4 + ;; + *) ;; + esac + setconfig vm_redir $vm_redir + setconfig vm_ipv4 "'$vm_ipv4'" + sleep 1 + set_redir_mod +} +set_ipv6() { #ipv6设置 + [ -z "$ipv6_redir" ] && ipv6_redir=未开启 + [ -z "$ipv6_dns" ] && ipv6_dns=已开启 + [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 + echo "-----------------------------------------------" + echo -e " 1 ipv6透明代理: \033[36m$ipv6_redir\033[0m ——代理ipv6流量" + [ "$disoverride" != "1" ] && echo -e " 2 ipv6-DNS解析: \033[36m$ipv6_dns\033[0m ——决定内置DNS是否返回ipv6地址" + echo -e " 3 CNV6绕过内核: \033[36m$cn_ipv6_route\033[0m ——优化性能,不兼容fake-ip" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + if [ "$ipv6_redir" = "未开启" ]; then + ipv6_support=已开启 + ipv6_redir=已开启 + sleep 2 + else + ipv6_redir=未开启 + fi + setconfig ipv6_redir $ipv6_redir + setconfig ipv6_support $ipv6_support + set_ipv6 + ;; + 2) + [ "$ipv6_dns" = "未开启" ] && ipv6_dns=已开启 || ipv6_dns=未开启 + setconfig ipv6_dns $ipv6_dns + set_ipv6 + ;; + 3) + if [ "$ipv6_redir" = "未开启" ]; then + ipv6_support=已开启 + ipv6_redir=已开启 + setconfig ipv6_redir $ipv6_redir + setconfig ipv6_support $ipv6_support + fi + if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = nftables ]; then + [ "$cn_ipv6_route" = "未开启" ] && cn_ipv6_route=已开启 || cn_ipv6_route=未开启 + setconfig cn_ipv6_route $cn_ipv6_route + else + echo -e "\033[31m当前设备缺少ipset模块或防火墙未使用nftables,无法启用绕过功能!!\033[0m" + sleep 1 + fi + set_ipv6 + ;; + *) + errornum + ;; + esac +} diff --git a/scripts/task.sh b/scripts/menus/task.sh similarity index 99% rename from scripts/task.sh rename to scripts/menus/task.sh index dbcfdb86..28f3f270 100644 --- a/scripts/task.sh +++ b/scripts/menus/task.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/ash # Copyright (C) Juewuy #加载全局变量 diff --git a/scripts/menus/tools.sh b/scripts/menus/tools.sh new file mode 100644 index 00000000..4a392f01 --- /dev/null +++ b/scripts/menus/tools.sh @@ -0,0 +1,884 @@ +#!/bin/sh +# Copyright (C) Juewuy +#工具脚本 +#工具与优化 +tools() { + ssh_tools() { + stop_iptables() { + iptables -w -t nat -D PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 + ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 + } + [ -n "$(cat /etc/firewall.user 2>&1 | grep '启用外网访问SSH服务')" ] && ssh_ol=禁止 || ssh_ol=开启 + [ -z "$ssh_port" ] && ssh_port=10022 + echo "-----------------------------------------------" + echo -e "\033[33m此功能仅针对使用Openwrt系统的设备生效,且不依赖服务\033[0m" + echo -e "\033[31m本功能不支持红米AX6S等镜像化系统设备,请勿尝试!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[32m修改\033[0m外网访问端口:\033[36m$ssh_port\033[0m" + echo -e " 2 \033[32m修改\033[0mSSH访问密码(请连续输入2次后回车)" + echo -e " 3 \033[33m$ssh_ol\033[0m外网访问SSH" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + read -p "请输入端口号(1000-65535) > " num + if [ -z "$num" ]; then + errornum + elif [ $num -gt 65535 -o $num -le 999 ]; then + echo -e "\033[31m输入错误!请输入正确的数值(1000-65535)!\033[0m" + elif [ -n "$(netstat -ntul | grep :$num)" ]; then + echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" + else + ssh_port=$num + setconfig ssh_port $ssh_port + sed -i "/启用外网访问SSH服务/d" /etc/firewall.user + stop_iptables + echo -e "\033[32m设置成功,请重新开启外网访问SSH功能!!!\033[0m" + fi + sleep 1 + ssh_tools + ;; + 2) + passwd + sleep 1 + ssh_tools + ;; + 3) + if [ "$ssh_ol" = "开启" ]; then + iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 + [ -n "$(ckcmd ip6tables)" ] && ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 + echo "iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user + [ -n "$(ckcmd ip6tables)" ] && echo "ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user + echo "-----------------------------------------------" + echo -e "已开启外网访问SSH功能!" + else + sed -i "/启用外网访问SSH服务/d" /etc/firewall.user + stop_iptables + echo "-----------------------------------------------" + echo -e "已禁止外网访问SSH!" + fi + ;; + *) + errornum + ;; + esac + } + #获取设置默认显示 + grep -qE "^\s*[^#].*otapredownload" /etc/crontabs/root >/dev/null 2>&1 && mi_update=禁用 || mi_update=启用 + [ "$mi_mi_autoSSH" = "已配置" ] && mi_mi_autoSSH_type=32m已配置 || mi_mi_autoSSH_type=31m未配置 + [ -f "$CRASHDIR"/tools/tun.ko ] && mi_tunfix=32m已启用 || mi_tunfix=31m未启用 + # + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用其他工具菜单:\033[0m" + echo -e "\033[33m本页工具可能无法兼容全部Linux设备,请酌情使用!\033[0m" + echo -e "磁盘占用/所在目录:" + du -sh "$CRASHDIR" + echo "-----------------------------------------------" + echo -e " 1 ShellCrash\033[33m测试菜单\033[0m" + echo -e " 2 ShellCrash\033[32m新手引导\033[0m" + echo -e " 3 \033[36m日志及推送工具\033[0m" + [ -f /etc/firewall.user ] && echo -e " 4 \033[32m配置\033[0m外网访问SSH" + [ -x /usr/sbin/otapredownload ] && echo -e " 5 \033[33m$mi_update\033[0m小米系统自动更新" + [ "$systype" = "mi_snapshot" ] && echo -e " 6 小米设备软固化SSH ———— \033[$mi_mi_autoSSH_type \033[0m" + [ "$systype" = "mi_snapshot" ] && echo -e " 8 小米设备Tun模块修复 ———— \033[$mi_tunfix \033[0m" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + errornum + elif [ "$num" = 0 ]; then + i= + + elif [ "$num" = 1 ]; then + testcommand + + elif [ "$num" = 2 ]; then + userguide + + elif [ "$num" = 3 ]; then + log_pusher + tools + + elif [ "$num" = 4 ]; then + ssh_tools + sleep 1 + tools + + elif [ "$num" = 7 ]; then + echo "-----------------------------------------------" + if [ ! -f "$CRASHDIR"/tools/ShellDDNS.sh ]; then + echo -e "正在获取在线脚本……" + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/ShellDDNS.sh tools/ShellDDNS.sh + if [ "$?" = "0" ]; then + mv -f "$TMPDIR"/ShellDDNS.sh "$CRASHDIR"/tools/ShellDDNS.sh + . "$CRASHDIR"/tools/ShellDDNS.sh + else + echo -e "\033[31m文件下载失败!\033[0m" + fi + else + . "$CRASHDIR"/tools/ShellDDNS.sh + fi + sleep 1 + tools + + elif [ -x /usr/sbin/otapredownload ] && [ "$num" = 5 ]; then + if [ "$mi_update" = "禁用" ]; then + grep -q "otapredownload" /etc/crontabs/root && + sed -i "/^[^\#]*otapredownload/ s/^/#/" /etc/crontabs/root || + echo "#15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root + else + grep -q "otapredownload" /etc/crontabs/root && + sed -i "/^\s*#.*otapredownload/ s/^\s*#//" /etc/crontabs/root || + echo "15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root + fi + echo "-----------------------------------------------" + echo -e "已\033[33m$mi_update\033[0m小米路由器的自动更新,如未生效,请在官方APP中同步设置!" + sleep 1 + tools + + elif [ "$num" = 6 ]; then + if [ "$systype" = "mi_snapshot" ]; then + mi_autoSSH + else + echo "不支持的设备!" + fi + tools + elif [ "$num" = 8 ]; then + if [ -f "$CRASHDIR"/tools/tun.ko ]; then + read -p "是否禁用此功能并移除相关补丁?(1/0) > " res + [ "$res" = 1 ] && { + rm -rf "$CRASHDIR"/tools/tun.ko + echo -e "\033[33m补丁文件已移除,请立即重启设备以防止出错!\033[0m" + } + elif ckcmd modinfo && [ -z "$(modinfo tun)" ]; then + echo -e "\033[33m本功能需要修改系统文件,不保证没有任何风险!\033[0m" + echo -e "\033[33m本功能采集的Tun模块并不一定适用于你的设备!\033[0m" + sleep 1 + read -p "我已知晓,出现问题会自行承担!(1/0) > " res + if [ "$res" = 1 ]; then + echo "-----------------------------------------------" + echo "正在连接服务器获取Tun模块补丁文件…………" + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/tun.ko bin/fix/tun.ko + if [ "$?" = "0" ]; then + mv -f "$TMPDIR"/tun.ko "$CRASHDIR"/tools/tun.ko && + "$CRASHDIR"/misnap_init.sh tunfix && + echo -e "\033[32m设置成功!请重启服务!\033[0m" + else + echo -e "\033[31m文件下载失败,请重试!\033[0m" + fi + fi + else + echo -e "\033[31m当前设备无需设置,请勿尝试!\033[0m" + sleep 1 + fi + tools + else + errornum + fi +} + +mi_autoSSH() { + echo "-----------------------------------------------" + echo -e "\033[33m本功能使用软件命令进行固化不保证100%成功!\033[0m" + echo -e "\033[33m如有问题请加群反馈:\033[36;4mhttps://t.me/ShellClash\033[0m" + read -p "请输入需要还原的SSH密码(不影响当前密码,回车可跳过) > " mi_mi_autoSSH_pwd + mi_mi_autoSSH=已配置 + cp -f /etc/dropbear/dropbear_rsa_host_key "$CRASHDIR"/configs/dropbear_rsa_host_key 2>/dev/null + cp -f /etc/dropbear/authorized_keys "$CRASHDIR"/configs/authorized_keys 2>/dev/null + ckcmd nvram && { + nvram set ssh_en=1 + nvram set telnet_en=1 + nvram set uart_en=1 + nvram set boot_wait=on + nvram commit + } + echo -e "\033[32m设置成功!\033[0m" + setconfig mi_mi_autoSSH $mi_mi_autoSSH + setconfig mi_mi_autoSSH_pwd $mi_mi_autoSSH_pwd + sleep 1 +} +#日志菜单 +log_pusher() { + [ -n "$push_TG" ] && stat_TG=32m已启用 || stat_TG=33m未启用 + [ -n "$push_Deer" ] && stat_Deer=32m已启用 || stat_Deer=33m未启用 + [ -n "$push_bark" ] && stat_bark=32m已启用 || stat_bark=33m未启用 + [ -n "$push_Po" ] && stat_Po=32m已启用 || stat_Po=33m未启用 + [ -n "$push_PP" ] && stat_PP=32m已启用 || stat_PP=33m未启用 + [ -n "$push_SynoChat" ] && stat_SynoChat=32m已启用 || stat_SynoChat=33m未启用 + [ -n "$push_Gotify" ] && stat_Gotify=32m已启用 || stat_Gotify=33m未启用 + [ "$task_push" = 1 ] && stat_task=32m已启用 || stat_task=33m未启用 + [ -n "$device_name" ] && device_s=32m$device_name || device_s=33m未设置 + echo "-----------------------------------------------" + echo -e " 1 Telegram推送 ——\033[$stat_TG\033[0m" + echo -e " 2 PushDeer推送 ——\033[$stat_Deer\033[0m" + echo -e " 3 Bark推送-IOS ——\033[$stat_bark\033[0m" + echo -e " 4 Passover推送 ——\033[$stat_Po\033[0m" + echo -e " 5 PushPlus推送 ——\033[$stat_PP\033[0m" + echo -e " 6 SynoChat推送 ——\033[$stat_SynoChat\033[0m" + echo -e " 7 Gotify推送 ——\033[$stat_Gotify\033[0m" + echo "-----------------------------------------------" + echo -e " a 查看\033[36m运行日志\033[0m" + echo -e " b 推送任务日志 ——\033[$stat_task\033[0m" + echo -e " c 设置设备名称 ——\033[$device_s\033[0m" + echo -e " d 清空日志文件" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + a) + if [ -s "$TMPDIR"/ShellCrash.log ]; then + echo "-----------------------------------------------" + cat "$TMPDIR"/ShellCrash.log + exit 0 + else + echo -e "\033[31m未找到相关日志!\033[0m" + fi + sleep 1 + ;; + 1) + echo "-----------------------------------------------" + if [ -n "$push_TG" ]; then + read -p "确认关闭TG日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_TG= + chat_ID= + setconfig push_TG + setconfig chat_ID + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + private_bot() { + echo -e "请先通过 \033[32;4mhttps://t.me/BotFather\033[0m 申请TG机器人并获取其\033[36mAPI TOKEN\033[0m" + echo "-----------------------------------------------" + read -p "请输入你获取到的API TOKEN > " TOKEN + echo "-----------------------------------------------" + echo -e "请向\033[32m你申请的机器人\033[33m而不是BotFather!\033[0m" + url_tg=https://api.telegram.org/bot${TOKEN}/getUpdates + } + public_bot() { + echo -e "请向机器人:\033[32;4mhttps://t.me/ShellCrashtg_bot\033[0m" + TOKEN=publictoken + url_tg=https://tgbot.jwsc.eu.org/publictoken/getUpdates + } + set_bot() { + echo -e "发送此秘钥: \033[30;46m$public_key\033[0m" + echo "-----------------------------------------------" + read -p "我已经发送完成(1/0) > " res + if [ "$res" = 1 ]; then + [ -n "$authentication" ] && auth="$authentication@" + export https_proxy="http://${auth}127.0.0.1:$mix_port" + if curl --version >/dev/null 2>&1; then + chat=$(curl -kfsSl $url_tg 2>/dev/null) + else + chat=$(wget -Y on -q -O - $url_tg) + fi + [ -n "$chat" ] && chat_ID=$(echo $chat | sed 's/"update_id":/{\n"update_id":/g' | grep "$public_key" | head -n1 | grep -oE '"id":.*,"is_bot' | sed s'/"id"://' | sed s'/,"is_bot//') + [ -z "$chat_ID" ] && { + echo -e "\033[31m无法获取对话ID,请返回重新设置或手动输入ChatID!\033[0m" + echo -e "通常访问 \033[32;4m$url_tg\033[0m \n\033[36m即可看到ChatID\033[0m" + read -p "请手动输入ChatID > " chat_ID + } + if echo "$chat_ID" | grep -qE '^[0-9]{8,}$'; then + push_TG=$TOKEN + setconfig push_TG $TOKEN + setconfig chat_ID $chat_ID + "$CRASHDIR"/start.sh logger "已完成Telegram日志推送设置!" 32 + else + echo -e "\033[31m无法获取对话ID,请重新配置!\033[0m" + sleep 1 + chose_bot + fi + fi + } + chose_bot() { + public_key=$(cat /proc/sys/kernel/random/boot_id | sed 's/.*-//') + echo "-----------------------------------------------" + echo -e " 1 使用公共机器人 ——不依赖内核服务" + echo -e " 2 使用私人机器人 ——需要额外申请" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case $num in + 1) + public_bot + set_bot + ;; + 2) + private_bot + set_bot + ;; + *) + errornum + ;; + esac + } + chose_bot + fi + sleep 1 + log_pusher + ;; + 2) + echo "-----------------------------------------------" + if [ -n "$push_Deer" ]; then + read -p "确认关闭PushDeer日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Deer= + setconfig push_Deer + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先前往 \033[32;4mhttp://www.pushdeer.com/official.html\033[0m 扫码安装快应用或下载APP" + echo -e "打开快应用/APP,并完成登陆" + echo -e "\033[33m切换到「设备」标签页,点击右上角的加号,注册当前设备\033[0m" + echo -e "\033[36m切换到「秘钥」标签页,点击右上角的加号,创建一个秘钥,并复制\033[0m" + echo "-----------------------------------------------" + read -p "请输入你复制的秘钥 > " url + if [ -n "$url" ]; then + push_Deer=$url + setconfig push_Deer $url + "$CRASHDIR"/start.sh logger "已完成PushDeer日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + sleep 1 + fi + log_pusher + ;; + 3) + echo "-----------------------------------------------" + if [ -n "$push_bark" ]; then + read -p "确认关闭Bark日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_bark= + bark_param= + setconfig push_bark + setconfig bark_param + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "\033[33mBark推送仅支持IOS系统,其他平台请使用其他推送方式!\033[0m" + echo -e "\033[32m请安装Bark-IOS客户端,并在客户端中找到专属推送链接\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的Bark推送链接 > " url + if [ -n "$url" ]; then + push_bark=$url + setconfig push_bark $url + "$CRASHDIR"/start.sh logger "已完成Bark日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + sleep 1 + fi + log_pusher + ;; + 4) + echo "-----------------------------------------------" + if [ -n "$push_Po" ]; then + read -p "确认关闭Pushover日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Po= + push_Po_key= + setconfig push_Po + setconfig push_Po_key + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先通过 \033[32;4mhttps://pushover.net/\033[0m 注册账号并获取\033[36mUser Key\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的User Key > " key + if [ -n "$key" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m请检查注册邮箱,完成账户验证\033[0m" + read -p "我已经验证完成(1/0) > " + echo "-----------------------------------------------" + echo -e "请通过 \033[32;4mhttps://pushover.net/apps/build\033[0m 生成\033[36mAPI Token\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的API Token > " Token + if [ -n "$Token" ]; then + push_Po=$Token + push_Po_key=$key + setconfig push_Po $Token + setconfig push_Po_key $key + "$CRASHDIR"/start.sh logger "已完成Passover日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + 5) + echo "-----------------------------------------------" + if [ -n "$push_PP" ]; then + read -p "确认关闭PushPlus日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_PP= + setconfig push_PP + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先通过 \033[32;4mhttps://www.pushplus.plus/push1.html\033[0m 注册账号并获取\033[36mtoken\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的token > " Token + if [ -n "$Token" ]; then + push_PP=$Token + setconfig push_PP $Token + "$CRASHDIR"/start.sh logger "已完成PushPlus日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + 6) + echo "-----------------------------------------------" + if [ -n "$push_SynoChat" ]; then + read -p "确认关闭SynoChat日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_SynoChat= + setconfig push_SynoChat + } + else + echo "-----------------------------------------------" + read -p "请输入你的Synology DSM主页地址 > " URL + echo "-----------------------------------------------" + read -p "请输入你的Synology Chat Token > " TOKEN + echo "-----------------------------------------------" + echo -e '请通过"你的群晖地址/webapi/entry.cgi?api=SYNO.Chat.External&method=user_list&version=2&token=你的TOKEN"获取user_id' + echo "-----------------------------------------------" + read -p "请输入你的user_id > " USERID + if [ -n "$URL" ]; then + push_SynoChat=$USERID + setconfig push_SynoChat $USERID + setconfig push_ChatURL $URL + setconfig push_ChatTOKEN $TOKEN + setconfig push_ChatUSERID $USERID + "$CRASHDIR"/start.sh logger "已完成SynoChat日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + setconfig push_ChatURL + setconfig push_ChatTOKEN + setconfig push_ChatUSERID + push_SynoChat= + setconfig push_SynoChat + fi + fi + sleep 1 + log_pusher + ;; + # 在menu.sh的case $num in代码块中添加 + 7) + echo "-----------------------------------------------" + if [ -n "$push_Gotify" ]; then + read -p "确认关闭Gotify日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Gotify= + setconfig push_Gotify + } + else + echo -e "请先通过Gotify服务器获取推送URL" + echo -e "格式示例: https://gotify.example.com/message?token=你的应用令牌" + echo "-----------------------------------------------" + read -p "请输入你的Gotify推送URL > " url + if [ -n "$url" ]; then + push_Gotify=$url + setconfig push_Gotify "$url" + "$CRASHDIR"/start.sh logger "已完成Gotify日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + b) + [ "$task_push" = 1 ] && task_push='' || task_push=1 + setconfig task_push $task_push + sleep 1 + log_pusher + ;; + c) + read -p "请输入本设备自定义推送名称 > " device_name + setconfig device_name $device_name + sleep 1 + log_pusher + ;; + d) + echo -e "\033[33m运行日志及任务日志均已清空!\033[0m" + rm -rf "$TMPDIR"/ShellCrash.log + sleep 1 + log_pusher + ;; + *) errornum ;; + esac +} +#新手引导 +userguide(){ + + forwhat(){ + echo "-----------------------------------------------" + echo -e "\033[30;46m 欢迎使用ShellCrash新手引导! \033[0m" + echo "-----------------------------------------------" + echo -e "\033[33m请先选择你的使用环境: \033[0m" + echo -e "\033[0m(你之后依然可以在设置中更改各种配置)\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[32m路由设备配置局域网透明代理\033[0m" + echo -e " 2 \033[36mLinux设备仅配置本机代理\033[0m" + [ -f "$CFG_PATH.bak" ] && echo -e " 3 \033[33m还原之前备份的设置\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 1) + #设置运行模式 + redir_mod="混合模式" + [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] && { + if grep -qE '^TPROXY$' /proc/net/ip_tables_targets || modprobe xt_TPROXY >/dev/null 2>&1; then + redir_mod="Tproxy模式" + else + redir_mod="Redir模式" + fi + } + setconfig crashcore "meta" + setconfig redir_mod "$redir_mod" + setconfig dns_mod mix + setconfig firewall_area '1' + #默认启用绕过CN-IP + setconfig cn_ip_route 已开启 + #自动识别IPV6 + [ -n "$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g')" ] && { + setconfig ipv6_redir 已开启 + setconfig ipv6_support 已开启 + setconfig ipv6_dns 已开启 + setconfig cn_ipv6_route 已开启 + } + #设置开机启动 + [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ] && /etc/init.d/shellcrash enable + ckcmd systemctl && [ "$(cat /proc/1/comm)" = "systemd" ] && systemctl enable shellcrash.service > /dev/null 2>&1 + rm -rf "$CRASHDIR"/.dis_startup + autostart=enable + #检测IP转发 + if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "0" ];then + echo "-----------------------------------------------" + echo -e "\033[33m检测到你的设备尚未开启ip转发,局域网设备将无法正常连接网络,是否立即开启?\033[0m" + read -p "是否开启?(1/0) > " res + [ "$res" = 1 ] && { + echo 'net.ipv4.ip_forward = 1' >> /etc/sysctl.conf + sysctl -w net.ipv4.ip_forward=1 + } && echo "已成功开启ipv4转发,如未正常开启,请手动重启设备!" || echo "开启失败!请自行谷歌查找当前设备的开启方法!" + fi + #禁止docker启用的net.bridge.bridge-nf-call-iptables + sysctl -w net.bridge.bridge-nf-call-iptables=0 > /dev/null 2>&1 + sysctl -w net.bridge.bridge-nf-call-ip6tables=0 > /dev/null 2>&1 + ;; + 2) + setconfig redir_mod "Redir模式" + [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] && setconfig crashcore "clash" + setconfig common_ports "未开启" + setconfig firewall_area '2' + ;; + 3) + mv -f $CFG_PATH.bak $CFG_PATH + echo -e "\033[32m脚本设置已还原!\033[0m" + echo -e "\033[33m请重新启动脚本!\033[0m" + exit 0 + ;; + *) + errornum + forwhat + ;; + esac + } + forwhat + #检测小内存模式 + dir_size=$(dir_avail "$CRASHDIR") + if [ "$dir_size" -lt 10240 ];then + echo "-----------------------------------------------" + echo -e "\033[33m检测到你的安装目录空间不足10M,是否开启小闪存模式?\033[0m" + echo -e "\033[0m开启后核心及数据库文件将被下载到内存中,这将占用一部分内存空间\033[0m" + echo -e "\033[0m每次开机后首次运行服务时都会自动的重新下载相关文件\033[0m" + echo "-----------------------------------------------" + read -p "是否开启?(1/0) > " res + [ "$res" = 1 ] && { + BINDIR=/tmp/ShellCrash + setconfig BINDIR /tmp/ShellCrash "$CRASHDIR"/configs/command.env + } + fi + #检测及下载根证书 + openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" + [ ! -d "$openssldir/certs" ] && openssldir=/etc/ssl + if [ -d $openssldir/certs -a ! -f $openssldir/certs/ca-certificates.crt ];then + echo "-----------------------------------------------" + echo -e "\033[33m当前设备未找到根证书文件\033[0m" + echo "-----------------------------------------------" + read -p "是否下载并安装根证书?(1/0) > " res + [ "$res" = 1 ] && checkupdate && getcrt + fi + #设置加密DNS + if [ -s $openssldir/certs/ca-certificates.crt ];then + dns_nameserver='https://dns.alidns.com/dns-query, https://doh.pub/dns-query' + dns_fallback='https://cloudflare-dns.com/dns-query, https://dns.google/dns-query, https://doh.opendns.com/dns-query' + dns_resolver='https://223.5.5.5/dns-query, 2400:3200::1' + setconfig dns_nameserver "'$dns_nameserver'" + setconfig dns_fallback "'$dns_fallback'" + setconfig dns_resolver "'$dns_resolver'" + fi + #开启公网访问 + sethost(){ + read -p "请输入你的公网IP地址 > " host + echo $host | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' + if [ -z "$host" ];then + echo -e "\033[31m请输入正确的IP地址!\033[0m" + sethost + fi + } + if ckcmd systemctl;then + echo "-----------------------------------------------" + echo -e "\033[32m是否开启公网访问Dashboard面板及socks服务?\033[0m" + echo -e "注意当前设备必须有公网IP才能从公网正常访问" + echo -e "\033[31m此功能会增加暴露风险请谨慎使用!\033[0m" + echo -e "vps设备可能还需要额外在服务商后台开启相关端口" + read -p "现在开启?(1/0) > " res + if [ "$res" = 1 ];then + read -p "请先设置面板访问秘钥 > " secret + read -p "请先修改Socks服务端口(1-65535) > " mix_port + read -p "请先设置Socks服务密码(账号默认为crash) > " sec + [ -z "$sec" ] && authentication=crash:$sec + host=$(curl ip.sb 2>/dev/null | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + if [ -z "$host" ];then + sethost + fi + public_support=已开启 + setconfig secret $secret + setconfig mix_port $mix_port + setconfig host $host + setconfig public_support $public_support + setconfig authentication "'$authentication'" + fi + fi + #启用推荐的自动任务配置 + . "$CRASHDIR"/task/task.sh && task_recom + #小米设备软固化 + if [ "$systype" = "mi_snapshot" ];then + echo "-----------------------------------------------" + echo -e "\033[33m检测到为小米路由设备,启用软固化可防止路由升级后丢失SSH\033[0m" + read -p "是否启用软固化功能?(1/0) > " res + [ "$res" = 1 ] && mi_autoSSH + fi + #提示导入订阅或者配置文件 + [ ! -s "$CRASHDIR"/yamls/config.yaml -a ! -s "$CRASHDIR"/jsons/config.json ] && { + echo "-----------------------------------------------" + echo -e "\033[32m是否导入配置文件?\033[0m(这是运行前的最后一步)" + echo -e "\033[0m你必须拥有一份配置文件才能运行服务!\033[0m" + echo "-----------------------------------------------" + read -p "现在开始导入?(1/0) > " res + [ "$res" = 1 ] && inuserguide=1 && { + if [ -f "$CRASHDIR"/v2b_api.sh ];then + . "$CRASHDIR"/v2b_api.sh + else + set_core_config + fi + set_core_config + inuserguide="" + } + } + #回到主界面 + echo "-----------------------------------------------" + echo -e "\033[36m很好!现在只需要执行启动就可以愉快的使用了!\033[0m" + echo "-----------------------------------------------" + read -p "立即启动服务?(1/0) > " res + [ "$res" = 1 ] && start_core && sleep 2 + main_menu +} +#测试菜单 +testcommand(){ + echo "$crashcore" | grep -q 'singbox' && config_path=${JSONSDIR}/config.json || config_path=${YAMLSDIR}/config.yaml + echo "-----------------------------------------------" + echo -e "\033[30;47m这里是测试命令菜单\033[0m" + echo -e "\033[33m如遇问题尽量运行相应命令后截图提交issue或TG讨论组\033[0m" + echo "-----------------------------------------------" + echo " 1 Debug模式运行内核" + echo " 2 查看系统DNS端口(:53)占用 " + echo " 3 测试ssl加密(aes-128-gcm)跑分" + echo " 4 查看ShellCrash相关路由规则" + echo " 5 查看内核配置文件前40行" + echo " 6 测试代理服务器连通性(google.tw)" + echo "-----------------------------------------------" + echo " 0 返回上级目录!" + read -p "请输入对应数字 > " num + case "$num" in + 0) + main_menu + ;; + 1) + debug + testcommand + ;; + 2) + echo "-----------------------------------------------" + netstat -ntulp |grep 53 + echo "-----------------------------------------------" + echo -e "可以使用\033[44m netstat -ntulp |grep xxx \033[0m来查询任意(xxx)端口" + exit; + ;; + 3) + echo "-----------------------------------------------" + openssl speed -multi 4 -evp aes-128-gcm + echo "-----------------------------------------------" + exit; + ;; + 4) + if [ "$firewall_mod" = "nftables" ];then + nft list table inet shellcrash + else + [ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 -o "$vm_redir" = "已开启" ] && { + echo "----------------Redir+DNS---------------------" + iptables -t nat -L PREROUTING --line-numbers + iptables -t nat -L shellcrash_dns --line-numbers + [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && iptables -t nat -L shellcrash --line-numbers + [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { + echo "----------------Tun/Tproxy-------------------" + iptables -t mangle -L PREROUTING --line-numbers + iptables -t mangle -L shellcrash_mark --line-numbers + } + } + [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && { + echo "-------------OUTPUT-Redir+DNS----------------" + iptables -t nat -L OUTPUT --line-numbers + iptables -t nat -L shellcrash_dns_out --line-numbers + [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && iptables -t nat -L shellcrash_out --line-numbers + [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { + echo "------------OUTPUT-Tun/Tproxy---------------" + iptables -t mangle -L OUTPUT --line-numbers + iptables -t mangle -L shellcrash_mark_out --line-numbers + } + } + [ "$ipv6_redir" = "已开启" ] && { + [ "$firewall_area" = 1 -o "$firewall_area" = 3 ] && { + ip6tables -t nat -L >/dev/null 2>&1 && { + echo "-------------IPV6-Redir+DNS-------------------" + ip6tables -t nat -L PREROUTING --line-numbers + ip6tables -t nat -L shellcrashv6_dns --line-numbers + [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && ip6tables -t nat -L shellcrashv6 --line-numbers + } + [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { + echo "-------------IPV6-Tun/Tproxy------------------" + ip6tables -t mangle -L PREROUTING --line-numbers + ip6tables -t mangle -L shellcrashv6_mark --line-numbers + } + } + } + [ "$vm_redir" = "已开启" ] && { + echo "-------------vm-Redir-------------------" + iptables -t nat -L shellcrash_vm --line-numbers + iptables -t nat -L shellcrash_vm_dns --line-numbers + } + fi + exit; + ;; + 5) + echo "-----------------------------------------------" + sed -n '1,40p' ${config_path} + echo "-----------------------------------------------" + exit; + ;; + 6) + echo "注意:依赖curl(不支持wget),且测试结果不保证一定准确!" + delay=`curl -kx ${authentication}@127.0.0.1:$mix_port -o /dev/null -s -w '%{time_starttransfer}' 'https://google.tw' & { sleep 3 ; kill $! >/dev/null 2>&1 & }` > /dev/null 2>&1 + delay=`echo |awk "{print $delay*1000}"` > /dev/null 2>&1 + echo "-----------------------------------------------" + if [ `echo ${#delay}` -gt 1 ];then + echo -e "\033[32m连接成功!响应时间为:"$delay" ms\033[0m" + else + echo -e "\033[31m连接超时!请重试或检查节点配置!\033[0m" + fi + main_menu + ;; + *) + errornum + main_menu + ;; + esac +} +debug(){ + echo "$crashcore" | grep -q 'singbox' && config_tmp="$TMPDIR"/jsons || config_tmp="$TMPDIR"/config.yaml + echo "-----------------------------------------------" + echo -e "\033[36m注意:Debug运行均会停止原本的内核服务\033[0m" + echo -e "后台运行日志地址:\033[32m$TMPDIR/debug.log\033[0m" + echo -e "如长时间运行后台监测,日志等级推荐error!防止文件过大!" + echo -e "你也可以通过:\033[33mcrash -s debug 'warning'\033[0m 命令使用其他日志等级" + echo "-----------------------------------------------" + echo -e " 1 仅测试\033[32m$config_tmp\033[0m配置文件可用性" + echo -e " 2 前台运行\033[32m$config_tmp\033[0m配置文件,不配置防火墙劫持(\033[33m使用Ctrl+C手动停止\033[0m)" + echo -e " 3 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[31merror\033[0m" + echo -e " 4 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[32minfo\033[0m" + echo -e " 5 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[33mdebug\033[0m" + echo -e " 6 后台运行完整启动流程,并配置防火墙劫持,且将错误日志打印到闪存:\033[32m$CRASHDIR/debug.log\033[0m" + echo "-----------------------------------------------" + echo -e " 8 后台运行完整启动流程,输出执行错误并查找上下文,之后关闭进程" + [ -s "$TMPDIR"/jsons/inbounds.json ] && echo -e " 9 将\033[32m$config_tmp\033[0m下json文件合并为$TMPDIR/debug.json" + echo "-----------------------------------------------" + echo " 0 返回上级目录!" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + "$CRASHDIR"/start.sh stop + "$CRASHDIR"/start.sh bfstart + if echo "$crashcore" | grep -q 'singbox' ;then + "$TMPDIR"/CrashCore run -D "$BINDIR" -C "$TMPDIR"/jsons & + { sleep 4 ; kill $! >/dev/null 2>&1 & } + wait + else + "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml + fi + rm -rf "$TMPDIR"/CrashCore + echo "-----------------------------------------------" + exit + ;; + 2) + "$CRASHDIR"/start.sh stop + "$CRASHDIR"/start.sh bfstart + "$COMMAND" + rm -rf "$TMPDIR"/CrashCore + echo "-----------------------------------------------" + exit + ;; + 3) + "$CRASHDIR"/start.sh debug error + main_menu + ;; + 4) + "$CRASHDIR"/start.sh debug info + main_menu + ;; + 5) + "$CRASHDIR"/start.sh debug debug + main_menu + ;; + 6) + echo -e "频繁写入闪存会导致闪存寿命降低,如非遇到会导致设备死机或重启的bug,请勿使用此功能!" + read -p "是否继续?(1/0) > " res + [ "$res" = 1 ] && "$CRASHDIR"/start.sh debug debug flash + main_menu + ;; + 8) + $0 -d + main_menu + ;; + 9) + "$CRASHDIR"/start.sh core_check && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && echo -e "\033[32m合并成功!\033[0m" + rm -rf "$TMPDIR"/CrashCore + main_menu + ;; + *) + errornum + ;; + esac +} + diff --git a/scripts/menus/upgrade.sh b/scripts/menus/upgrade.sh new file mode 100644 index 00000000..7ef99843 --- /dev/null +++ b/scripts/menus/upgrade.sh @@ -0,0 +1,1079 @@ +#!/bin/sh +# Copyright (C) Juewuy + +. "$CRASHDIR"/libs/check_dir_avail.sh + +error_down(){ + echo -e "\033[33m请尝试切换至其他安装源后重新下载!\033[0m" + echo -e "或者参考 \033[32;4mhttps://juewuy.github.io/bdaz\033[0m 进行本地安装!" + sleep 1 +} +#主界面 +upgrade(){ + echo "-----------------------------------------------" + echo -ne "\033[32m正在检查更新!\033[0m\r" + checkupdate + [ -z "$core_v" ] && core_v=$crashcore + core_v_new=$(eval echo \$"$crashcore"_v) + echo -e "\033[30;47m欢迎使用更新功能:\033[0m" + echo "-----------------------------------------------" + echo -e "当前目录(\033[32m$CRASHDIR\033[0m)剩余空间:\033[36m$(dir_avail "$CRASHDIR" -h)\033[0m" + [ "$(dir_avail "$CRASHDIR")" -le 5120 ] && [ "$CRASHDIR" = "$BINDIR" ] && { + echo -e "\033[33m当前目录剩余空间较低,建议开启小闪存模式!\033[0m" + sleep 1 + } + echo "-----------------------------------------------" + echo -e " 1 更新\033[36m管理脚本 \033[33m$versionsh_l\033[0m > \033[32m$version_new \033[36m$release_type\033[0m" + echo -e " 2 切换\033[33m内核文件 \033[33m$core_v\033[0m > \033[32m$core_v_new\033[0m" + echo -e " 3 更新\033[32m数据库文件\033[0m > \033[32m$GeoIP_v\033[0m" + echo -e " 4 安装本地\033[35mDashboard\033[0m面板" + echo -e " 5 安装/更新本地\033[33m根证书文件\033[0m" + echo -e " 6 查看\033[32mPAC\033[0m自动代理配置" + echo "-----------------------------------------------" + echo -e " 7 切换\033[36m安装源\033[0m及\033[36m安装版本\033[0m" + echo -e " 8 \033[32m配置自动更新\033[0m" + echo -e " 9 \033[31m卸载ShellCrash\033[0m" + echo "-----------------------------------------------" + echo -e "99 \033[36m鸣谢!\033[0m" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + setscripts + ;; + 2) + setcore + upgrade + ;; + 3) + setgeo + upgrade + ;; + 4) + setdb + upgrade + ;; + 5) + setcrt + upgrade + ;; + 6) + echo "-----------------------------------------------" + echo -e "PAC配置链接为:\033[30;47m http://$host:$db_port/ui/pac \033[0m" + echo -e "PAC的使用教程请参考:\033[4;32mhttps://juewuy.github.io/ehRUeewcv\033[0m" + sleep 2 + upgrade + ;; + 7) + setserver + upgrade + ;; + 8) + . "$CRASHDIR"/task/task.sh && task_add + upgrade + ;; + 9) + uninstall + exit + ;; + 99) + echo "-----------------------------------------------" + echo -e "感谢:\033[32mClash项目 \033[0m作者\033[36m Dreamacro\033[0m" + echo -e "感谢:\033[32msing-box项目 \033[0m作者\033[36m SagerNet\033[0m 项目地址:\033[32mhttps://github.com/SagerNet/sing-box\033[0m" + echo -e "感谢:\033[32mMetaCubeX项目 \033[0m作者\033[36m MetaCubeX\033[0m 项目地址:\033[32mhttps://github.com/MetaCubeX\033[0m" + echo -e "感谢:\033[32mYACD面板项目 \033[0m作者\033[36m haishanh\033[0m 项目地址:\033[32mhttps://github.com/haishanh/yacd\033[0m" + echo -e "感谢:\033[32mzashboard项目 \033[0m作者\033[36m Zephyruso\033[0m 项目地址:\033[32mhttps://github.com/Zephyruso/zashboard\033[0m" + echo -e "感谢:\033[32mSubconverter \033[0m作者\033[36m tindy2013\033[0m 项目地址:\033[32mhttps://github.com/tindy2013/subconverter\033[0m" + echo -e "感谢:\033[32msing-box分支项目 \033[0m作者\033[36m PuerNya\033[0m 项目地址:\033[32mhttps://github.com/PuerNya/sing-box\033[0m" + echo -e "感谢:\033[32msing-box分支项目 \033[0m作者\033[36m reF1nd\033[0m 项目地址:\033[32mhttps://github.com/reF1nd/sing-box\033[0m" + echo -e "感谢:\033[32mDustinWin相关项目 \033[0m作者\033[36m DustinWin\033[0m 作者地址:\033[32mhttps://github.com/DustinWin\033[0m" + echo "-----------------------------------------------" + echo -e "特别感谢:\033[36m所有帮助及赞助过此项目的同仁们!\033[0m" + echo "-----------------------------------------------" + sleep 2 + upgrade + ;; + *) + errornum + ;; + esac +} +#检查更新 +checkupdate(){ + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/version_new version echooff + [ "$?" = "0" ] && { + version_new=$(cat "$TMPDIR"/version_new) + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/version_new bin/version echooff + } + if [ "$?" = "0" ];then + . "$TMPDIR"/version_new 2>/dev/null + else + echo -e "\033[31m检查更新失败!请尝试切换其他安装源!\033[0m" + setserver + [ "$checkupdate" = false ] || checkupdate + fi + rm -rf "$TMPDIR"/version_new +} +#更新脚本 +getscripts(){ + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz + if [ "$?" != "0" ];then + echo -e "\033[33m文件下载失败!\033[0m" + error_down + else + "$CRASHDIR"/start.sh stop 2>/dev/null + #解压 + echo "-----------------------------------------------" + echo "开始解压文件!" + mkdir -p "$CRASHDIR" > /dev/null + tar -zxf ""$TMPDIR"/ShellCrash.tar.gz" ${tar_para} -C "$CRASHDIR"/ + if [ $? -ne 0 ];then + echo -e "\033[33m文件解压失败!\033[0m" + error_down + else + . "$CRASHDIR"/init.sh >/dev/null + echo -e "\033[32m脚本更新成功!\033[0m" + fi + fi + rm -rf "$TMPDIR"/ShellCrash.tar.gz + exit +} +setscripts(){ + echo "-----------------------------------------------" + echo -e "当前脚本版本为:\033[33m $versionsh_l \033[0m" + echo -e "最新脚本版本为:\033[32m $version_new \033[0m" + echo -e "注意更新时会停止服务!" + echo "-----------------------------------------------" + read -p "是否更新脚本?[1/0] > " res + if [ "$res" = '1' ]; then + #下载更新 + getscripts + #提示 + echo "-----------------------------------------------" + echo -e "\033[32m管理脚本更新成功!\033[0m" + echo "-----------------------------------------------" + exit; + fi +} +#更新内核 +getcpucore(){ #自动获取内核架构 + cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]') + [ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="armv5" + [ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && [ ! -d /jffs ] && cpucore="armv7" + [ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="arm64" + [ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="386" + [ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="amd64" + if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ];then + mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}') #通过判断大小端判断mips或mipsle + [ "$mipstype" = "0" ] && cpucore="mips-softfloat" || cpucore="mipsle-softfloat" + fi + [ -n "$cpucore" ] && setconfig cpucore $cpucore +} +setcpucore(){ #手动设置内核架构 + cpucore_list="armv5 armv7 arm64 386 amd64 mipsle-softfloat mipsle-hardfloat mips-softfloat" + echo "-----------------------------------------------" + echo -e "\033[31m仅适合脚本无法正确识别核心或核心无法正常运行时使用!\033[0m" + echo -e "当前可供在线下载的处理器架构为:" + echo $cpucore_list | awk -F " " '{for(i=1;i<=NF;i++) {print i" "$i }}' + echo -e "不知道如何获取核心版本?请参考:\033[36;4mhttps://juewuy.github.io/bdaz\033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + [ -n "$num" ] && setcpucore=$(echo $cpucore_list | awk '{print $"'"$num"'"}' ) + if [ -z "$setcpucore" ];then + echo -e "\033[31m请输入正确的处理器架构!\033[0m" + sleep 1 + cpucore="" + else + cpucore=$setcpucore + setconfig cpucore $cpucore + fi +} +setcoretype(){ #手动指定内核类型 + echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash + echo -e "\033[33m请确认该自定义内核的类型:\033[0m" + echo -e " 1 Clash基础内核" + echo -e " 2 Clash-Premium内核" + echo -e " 3 Mihomo(Meta)内核" + echo -e " 4 Sing-Box内核" + echo -e " 5 Sing-Box-reF1nd内核" + read -p "请输入对应数字 > " num + case "$num" in + 2) crashcore=clashpre ;; + 3) crashcore=meta ;; + 4) crashcore=singbox ;; + 5) crashcore=singboxr ;; + *) crashcore=clash ;; + esac + echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash +} +switch_core(){ #clash与singbox内核切换 + #singbox和clash内核切换时提示是否保留文件 + [ "$core_new" != "$core_old" ] && { + [ "$dns_mod" = "redir_host" ] && [ "$core_old" = "clash" ] && setconfig dns_mod mix #singbox自动切换dns + [ "$dns_mod" = "mix" ] && [ "$crashcore" = 'clash' -o "$crashcore" = 'clashpre' ] && setconfig dns_mod fake-ip #singbox自动切换dns + echo -e "\033[33m已从$core_old内核切换至$core_new内核\033[0m" + echo -e "\033[33m二者Geo数据库及yaml/json配置文件不通用\033[0m" + read -p "是否保留相关数据库文件?(1/0) > " res + [ "$res" = '0' ] && { + [ "$core_old" = "clash" ] && { + geodate='Country.mmdb GeoSite.dat ruleset/*.mrs ruleset/*.yaml ruleset/*.yml' + geodate_v='Country_v cn_mini_v geosite_v mrs_geosite_cn_v' + } + [ "$core_old" = "singbox" ] && { + geodate='geoip.db geosite.db ruleset/*.srs ruleset/*.json' + geodate_v='geoip_cn_v geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v' + } + for text in ${geodate} ;do + rm -rf "$CRASHDIR"/${text} + done + for text in ${geodate_v} ;do + setconfig "$text" + done + } + } + if echo "$crashcore" | grep -q 'singbox';then + COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' + else + COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' + fi + setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env && . "$CRASHDIR"/configs/command.env +} +getcore(){ #下载内核文件 + [ -z "$crashcore" ] && crashcore=meta + [ -z "$cpucore" ] && getcpucore + echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash + #获取在线内核文件 + echo "-----------------------------------------------" + echo "正在在线获取$crashcore核心文件……" + if [ -n "$custcorelink" ];then + zip_type=$(echo $custcorelink | grep -oE 'tar.gz$') + [ -z "$zip_type" ] && zip_type=$(echo $custcorelink | grep -oE 'gz$') + if [ -n "$zip_type" ];then + "$CRASHDIR"/start.sh webget "$TMPDIR"/core_new.${zip_type} "$custcorelink" + else + echo -e "\033[31m链接不是以.tar.gz或.gz结尾!下载已取消!\033[0m" + exit + fi + else + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/core_new.tar.gz bin/${crashcore}/${core_new}-linux-${cpucore}.tar.gz + fi + if [ "$?" = "1" ];then + echo -e "\033[31m核心文件下载失败!\033[0m" + rm -rf "$TMPDIR"/core_new.tar.gz + [ -z "$custcorelink" ] && error_down + else + [ -n "$(pidof CrashCore)" ] && { + "$CRASHDIR"/start.sh stop #停止内核服务防止内存不足 + rm -rf "$TMPDIR"/CrashCore #删除缓存内核防止缓存空间不足 + } + [ -f "$TMPDIR"/core_new.tar.gz ] && { + mkdir -p "$TMPDIR"/core_tmp + [ "$BINDIR" = "$TMPDIR" ] && rm -rf "$TMPDIR"/CrashCore #小闪存模式防止空间不足 + tar -zxf ""$TMPDIR"/core_new.tar.gz" ${tar_para} -C "$TMPDIR"/core_tmp/ + for file in $(find "$TMPDIR"/core_tmp 2>/dev/null);do + [ -f $file ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|premium)')" ] && mv -f $file "$TMPDIR"/core_new + done + rm -rf "$TMPDIR"/core_tmp + } + [ -f "$TMPDIR"/core_new.gz ] && gunzip "$TMPDIR"/core_new.gz && rm -rf "$TMPDIR"/core_new.gz + chmod +x "$TMPDIR"/core_new + [ "$crashcore" = unknow ] && setcoretype + if echo "$crashcore" | grep -q 'singbox';then + core_v=$("$TMPDIR"/core_new version 2>/dev/null | grep version | awk '{print $3}') + else + core_v=$("$TMPDIR"/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') + fi + if [ -z "$core_v" ];then + echo -e "\033[31m核心文件下载成功但校验失败!请尝试手动指定CPU版本\033[0m" + rm -rf "$TMPDIR"/core_new + rm -rf "$TMPDIR"/core_new.tar.gz + setcpucore + else + echo -e "\033[32m$crashcore核心下载成功!\033[0m" + sleep 1 + mv -f "$TMPDIR"/core_new "$TMPDIR"/CrashCore + if [ -f "$TMPDIR"/core_new.tar.gz ];then + mv -f "$TMPDIR"/core_new.tar.gz "$BINDIR"/CrashCore.tar.gz + else + tar -zcf "$BINDIR"/CrashCore.tar.gz ${tar_para} -C "$TMPDIR" CrashCore + fi + setconfig crashcore $crashcore + setconfig core_v $core_v + setconfig custcorelink $custcorelink + switch_core + fi + fi +} +setcustcore(){ #自定义内核 + checkcustcore(){ + [ "$api_tag" = "latest" ] && api_url=latest || api_url="tags/$api_tag" + #通过githubapi获取内核信息 + echo -e "\033[32m正在获取内核文件链接!\033[0m" + "$CRASHDIR"/start.sh webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url} + if [ "$?" = 0 ];then + release_tag=$(cat "$TMPDIR"/github_api | grep '"tag_name":' | awk -F '"' '{print $4}') + release_date=$(cat "$TMPDIR"/github_api | grep '"published_at":' | awk -F '"' '{print $4}') + update_date=$(cat "$TMPDIR"/github_api | grep '"updated_at":' | head -n 1 | awk -F '"' '{print $4}') + [ -n "$(echo $cpucore | grep mips)" ] && cpu_type=mips || cpu_type=$cpucore + cat "$TMPDIR"/github_api | grep "browser_download_url" | grep -oE "https://github.com/${project}/releases/download.*linux.*${cpu_type}.*\.gz\"$" | sed 's/"//' > "$TMPDIR"/core.list + rm -rf "$TMPDIR"/github_api + # + if [ -s "$TMPDIR"/core.list ];then + echo "-----------------------------------------------" + echo -e "内核版本:\033[36m$release_tag\033[0m" + echo -e "发布时间:\033[33m$release_date\033[0m" + echo -e "更新时间:\033[32m$update_date\033[0m" + echo "-----------------------------------------------" + echo -e "\033[33m请确认内核信息并选择:\033[0m" + cat "$TMPDIR"/core.list | grep -oE "$release_tag.*" | sed 's|.*/||' | awk '{print " "NR" "$1}' + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + setcustcore + ;; + [1-9]|[1-9][0-9]) + if [ "$num" -le "$(wc -l < "$TMPDIR"/core.list)" ];then + custcorelink=$(sed -n "$num"p "$TMPDIR"/core.list) + getcore + else + errornum + fi + ;; + *) + errornum + ;; + esac + else + echo -e "\033[31m找不到可用内核,可能是作者没有编译相关CPU架构版本的内核文件!\033[0m" + sleep 1 + fi + else + echo -e "\033[31m查找失败,请尽量在服务启动后再使用本功能!\033[0m" + sleep 1 + fi + rm -rf "$TMPDIR"/core.list + } + [ -z "$cpucore" ] && getcpucore + echo "-----------------------------------------------" + echo -e "\033[36m此处内核通常源自互联网采集,此处致谢各位开发者!\033[0m" + echo -e "\033[33m自定义内核未经过完整适配,使用出现问题请自行解决!\033[0m" + echo -e "\033[31m自定义内核已适配定时任务,但不支持小闪存模式!\033[0m" + echo -e "\033[32m如遇到网络错误请先启动ShellCrash服务!\033[0m" + [ -n "$custcore" ] && { + echo "-----------------------------------------------" + echo -e "当前内核为:\033[36m$custcore\033[0m" + } + echo "-----------------------------------------------" + echo -e "\033[33m请选择需要使用的核心!\033[0m" + echo -e "1 \033[36mMetaCubeX/mihomo\033[32m@release\033[0m版本官方内核" + echo -e "2 \033[36mMetaCubeX/mihomo\033[32m@alpha\033[0m版本官方内核" + echo -e "3 \033[36mvernesong/mihomo\033[32m@alpha\033[0m版本内核(支持Smart策略)" + echo -e "4 \033[36mSagerNet/sing-box\033[32m@release\033[0m版本官方内核" + echo -e "5 \033[36mreF1nd/sing-box\033[32m@release\033[0m版本内核(完整编译)" + echo -e "6 \033[36mreF1nd/sing-box\033[32m@dev\033[0m版本内核(完整编译)" + echo -e "7 Premium-2023.08.17内核(已停止维护)" + echo -e "a \033[33m自定义内核链接 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 1) + project=MetaCubeX/mihomo + api_tag=latest + crashcore=meta + checkcustcore + ;; + 2) + project=MetaCubeX/mihomo + api_tag=Prerelease-Alpha + crashcore=meta + checkcustcore + ;; + 3) + project=vernesong/mihomo + api_tag=Prerelease-Alpha + crashcore=meta + checkcustcore + ;; + 4) + project=SagerNet/sing-box + api_tag=latest + crashcore=singbox + checkcustcore + ;; + 5) + project=juewuy/ShellCrash + api_tag=singbox_core_reF1nd + crashcore=singboxr + checkcustcore + ;; + 6) + project=juewuy/ShellCrash + api_tag=singbox_core_dev_reF1nd + crashcore=singboxr + checkcustcore + ;; + 7) + project=juewuy/ShellCrash + api_tag=clash.premium.latest + crashcore=clashpre + checkcustcore + ;; + a) + read -p "请输入自定义内核的链接地址(必须是以.tar.gz或.gz结尾的压缩文件) > " link + [ -n "$link" ] && custcorelink="$link" + crashcore=unknow + getcore + ;; + *) + errornum + ;; + esac +} +setcore(){ #内核选择菜单 + #获取核心及版本信息 + [ -z "$crashcore" ] && crashcore="unknow" + [ ! -f "$CRASHDIR"/CrashCore.tar.gz -o ! -f "$BINDIR"/CrashCore.tar.gz ] && crashcore="未安装核心" + echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash + [ -n "$custcorelink" ] && custcore="$(echo $custcorelink | sed 's#.*github.com##; s#/releases/download/#@#; s#-linux.*$##')" + ### + echo "-----------------------------------------------" + [ -z "$cpucore" ] && getcpucore + echo -e "当前内核:\033[42;30m $crashcore \033[47;30m$core_v\033[0m" + echo -e "当前系统处理器架构:\033[32m $cpucore \033[0m" + echo -e "\033[33m请选择需要使用的核心版本!\033[0m" + echo -e "\033[36m如需本地上传,请将二进制文件上传至 /tmp 目录后重新运行crash命令\033[0m" + echo "-----------------------------------------------" + echo -e "1 \033[43;30m Mihomo \033[0m: \033[32m(原meta内核)支持全面\033[0m" + echo -e " >>\033[32m$meta_v \033[33m占用略高\033[0m" + echo -e " 说明文档: \033[36;4mhttps://wiki.metacubex.one\033[0m" + echo -e "2 \033[43;30m SingBoxR \033[0m: \033[32m支持全面\033[0m" + echo -e " >>\033[32m$singboxr_v \033[33m使用reF1nd增强分支\033[0m" + echo -e " 说明文档: \033[36;4mhttps://sing-boxr.dustinwin.us.kg\033[0m" + echo -e "3 \033[43;30m SingBox \033[0m: \033[32m占用较低\033[0m" + echo -e " >>\033[32m$singbox_v \033[33m不支持providers\033[0m" + echo -e " 说明文档: \033[36;4mhttps://sing-box.sagernet.org\033[0m" + echo -e "4 \033[43;30m Clash \033[0m: \033[32m占用低\033[0m" + echo -e " >>\033[32m$clash_v \033[33m不安全,已停止维护\033[0m" + echo -e " 说明文档: \033[36;4mhttps://lancellc.gitbook.io\033[0m" + echo "-----------------------------------------------" + echo -e "5 \033[36m自定义内核\033[0m $custcore" + echo -e "6 \033[32m更新当前内核\033[0m" + echo "-----------------------------------------------" + echo "9 手动指定处理器架构" + echo "-----------------------------------------------" + echo 0 返回上级菜单 + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + [ -d "/jffs" ] && { + echo -e "\033[31mMeta内核使用的GeoSite.dat数据库在华硕设备存在被系统误删的问题,可能无法使用!\033[0m" + sleep 3 + } + crashcore=meta + custcorelink='' + getcore + ;; + 2) + crashcore=singboxr + custcorelink='' + getcore + ;; + 3) + crashcore=singbox + custcorelink='' + getcore + ;; + 4) + crashcore=clash + custcorelink='' + getcore + ;; + 5) + setcustcore + setcore + ;; + 6) + getcore + ;; + 9) + setcpucore + ;; + *) + errornum + ;; + esac +} +#数据库 +getgeo(){ #下载Geo文件 + #生成链接 + echo "-----------------------------------------------" + echo 正在从服务器获取数据库文件………… + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype + if [ "$?" = "1" ];then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "$geoname" | grep -Eq '.mrs|.srs|.tar.gz' && { + geofile='ruleset/' + [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset + } + if echo "$geoname" | grep -Eq '.tar.gz';then + tar -zxf "$TMPDIR"/${geoname} ${tar_para} -C "$BINDIR"/${geofile} > /dev/null + [ $? -ne 0 ] && echo "文件解压失败!" && rm -rf "$TMPDIR"/${geoname} && exit 1 + rm -rf "$TMPDIR"/${geoname} + else + mv -f "$TMPDIR"/${geoname} "$BINDIR"/${geofile}${geoname} + fi + echo "-----------------------------------------------" + echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" + geo_v="$(echo $geotype | awk -F "." '{print $1}')_v" + setconfig $geo_v $GeoIP_v + fi + sleep 1 +} +setcustgeo(){ #下载自定义数据库文件 + getcustgeo(){ + echo "-----------------------------------------------" + echo "正在获取数据库文件…………" + "$CRASHDIR"/start.sh webget "$TMPDIR"/$geoname $custgeolink + if [ "$?" = "1" ];then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "$geoname" | grep -Eq '.mrs|.srs' && { + geofile='ruleset/' + [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset + } + mv -f "$TMPDIR"/${geoname} "$BINDIR"/${geofile}${geoname} + echo "-----------------------------------------------" + echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" + fi + sleep 1 + } + checkcustgeo(){ + [ "$api_tag" = "latest" ] && api_url=latest || api_url="tags/$api_tag" + [ ! -s "$TMPDIR"/geo.list ] && { + echo -e "\033[32m正在查找可更新的数据库文件!\033[0m" + "$CRASHDIR"/start.sh webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url} + release_tag=$(cat "$TMPDIR"/github_api | grep '"tag_name":' | awk -F '"' '{print $4}') + cat "$TMPDIR"/github_api | grep "browser_download_url" | grep -oE 'releases/download.*' | grep -oiE 'geosite.*\.dat"$|country.*\.mmdb"$|.*.mrs|.*.srs' | sed 's|.*/||' | sed 's/"//' > "$TMPDIR"/geo.list + rm -rf "$TMPDIR"/github_api + } + if [ -s "$TMPDIR"/geo.list ];then + echo -e "请选择需要更新的数据库文件:" + echo "-----------------------------------------------" + cat "$TMPDIR"/geo.list | awk '{print " "NR" "$1}' + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + [1-99]) + if [ "$num" -le "$(wc -l < "$TMPDIR"/geo.list)" ];then + geotype=$(sed -n "$num"p "$TMPDIR"/geo.list) + [ -n "$(echo $geotype | grep -oiE 'GeoSite.*dat')" ] && geoname=GeoSite.dat + [ -n "$(echo $geotype | grep -oiE 'Country.*mmdb')" ] && geoname=Country.mmdb + [ -n "$(echo $geotype | grep -oiE '.*(.srs|.mrs)')" ] && geoname=$geotype + custgeolink=https://github.com/${project}/releases/download/${release_tag}/${geotype} + getcustgeo + checkcustgeo + else + errornum + fi + ;; + *) + errornum + ;; + esac + else + echo -e "\033[31m查找失败,请尽量在服务启动后再使用本功能!\033[0m" + sleep 1 + fi + } + rm -rf "$TMPDIR"/geo.list + echo "-----------------------------------------------" + echo -e "\033[36m此处数据库均源自互联网采集,此处致谢各位开发者!\033[0m" + echo -e "\033[32m请点击或复制链接前往项目页面查看具体说明!\033[0m" + echo -e "\033[31m自定义数据库不支持定时任务及小闪存模式!\033[0m" + echo -e "\033[33m如遇到网络错误请先启动ShellCrash服务!\033[0m" + echo -e "\033[0m请选择需要更新的数据库项目来源:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[36;4mhttps://github.com/MetaCubeX/meta-rules-dat\033[0m (仅限Clash/Mihomo)" + echo -e " 2 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Clash/Mihomo)" + echo -e " 3 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限SingBox-srs)" + echo -e " 4 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Mihomo-mrs)" + echo -e " 5 \033[36;4mhttps://github.com/Loyalsoldier/geoip\033[0m (仅限Clash-GeoIP)" + echo "-----------------------------------------------" + echo -e " 9 \033[33m自定义数据库链接 \033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + project=MetaCubeX/meta-rules-dat + api_tag=latest + checkcustgeo + setcustgeo + ;; + 2) + project=DustinWin/ruleset_geodata + api_tag=mihomo-geodata + checkcustgeo + setcustgeo + ;; + 3) + project=DustinWin/ruleset_geodata + api_tag=sing-box-ruleset + checkcustgeo + setcustgeo + ;; + 4) + project=DustinWin/ruleset_geodata + api_tag=mihomo-ruleset + checkcustgeo + setcustgeo + ;; + 5) + project=Loyalsoldier/geoip + api_tag=latest + checkcustgeo + setcustgeo + ;; + 9) + read -p "请输入自定义数据库的链接地址 > " link + [ -n "$link" ] && custgeolink="$link" + getgeo + setcustgeo + ;; + *) + errornum + ;; + esac +} +setgeo(){ + . $CFG_PATH > /dev/null + [ -n "$cn_mini_v" ] && geo_type_des=精简版 || geo_type_des=全球版 + echo "-----------------------------------------------" + echo -e "\033[36m请选择需要更新的Geo数据库文件:\033[0m" + echo -e "\033[36mMihomo内核和SingBox内核的数据库文件不通用\033[0m" + echo -e "在线数据库最新版本(每日同步上游):\033[32m$GeoIP_v\033[0m" + echo "-----------------------------------------------" + echo -e " 1 CN-IP绕过文件(约0.1mb) \033[33m$china_ip_list_v\033[0m" + echo -e " 2 CN-IPV6绕过文件(约30kb) \033[33m$china_ipv6_list_v\033[0m" + echo "-----------------------------------------------" + echo -e " 3 Mihomo精简版GeoIP_cn数据库(约0.1mb) \033[33m$cn_mini_v\033[0m" + echo -e " 4 Mihomo完整版GeoSite数据库(约5mb) \033[33m$geosite_v\033[0m" + echo -e " 5 Mihomo-mrs数据库常用包(约1mb) \033[33m$mrs_v\033[0m" + echo "-----------------------------------------------" + echo -e " 6 Singbox-srs数据库常用包(约0.8mb) \033[33m$srs_v\033[0m" + echo "-----------------------------------------------" + echo -e " 8 \033[32m自定义数据库文件\033[0m" + echo -e " 9 \033[31m清理数据库文件\033[0m" + echo " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + ;; + 1) + geotype=china_ip_list.txt + geoname=cn_ip.txt + getgeo + setgeo + ;; + 2) + geotype=china_ipv6_list.txt + geoname=cn_ipv6.txt + getgeo + setgeo + ;; + 3) + geotype=cn_mini.mmdb + geoname=Country.mmdb + getgeo + setgeo + ;; + 4) + geotype=geosite.dat + geoname=GeoSite.dat + getgeo + setgeo + ;; + 5) + geotype=mrs.tar.gz + geoname=mrs.tar.gz + getgeo + setgeo + ;; + 6) + geotype=srs.tar.gz + geoname=srs.tar.gz + getgeo + setgeo + ;; + 8) + setcustgeo + setgeo + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[33m这将清理$CRASHDIR目录及/ruleset目录下所有数据库文件!\033[0m" + echo -e "\033[36m清理后启动服务即可自动下载所需文件~\033[0m" + echo "-----------------------------------------------" + read -p "确认清理?[1/0] > " res + [ "$res" = '1' ] && { + for file in cn_ip.txt cn_ipv6.txt Country.mmdb GeoSite.dat geoip.db geosite.db;do + rm -rf $CRASHDIR/$file + done + for var in Country_v cn_mini_v china_ip_list_v china_ipv6_list_v geosite_v geoip_cn_v geosite_cn_v mrs_geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v mrs_v srs_v;do + setconfig $var + done + rm -rf $CRASHDIR/ruleset/* + echo -e "\033[33m所有数据库文件均已清理!\033[0m" + sleep 1 + } + setgeo + ;; + *) + errornum + ;; +esac +} +#Dashboard +getdb(){ + dblink="${update_url}/" + echo "-----------------------------------------------" + echo 正在连接服务器获取安装文件………… + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz + if [ "$?" = "1" ];then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + echo "-----------------------------------------------" + error_down + setdb + else + echo -e "\033[33m下载成功,正在解压文件!\033[0m" + mkdir -p $dbdir > /dev/null + tar -zxf ""$TMPDIR"/clashdb.tar.gz" ${tar_para} -C $dbdir > /dev/null + [ $? -ne 0 ] && echo "文件解压失败!" && rm -rf "$TMPDIR"/clashfm.tar.gz && exit 1 + #修改默认host和端口 + if [ "$db_type" = "clashdb" -o "$db_type" = "meta_db" -o "$db_type" = "zashboard" ];then + sed -i "s/127.0.0.1/${host}/g" $dbdir/assets/*.js + sed -i "s/9090/${db_port}/g" $dbdir/assets/*.js + elif [ "$db_type" = "meta_xd" ];then + sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" $dbdir/_nuxt/*.js + else + sed -i "s/127.0.0.1:9090/${host}:${db_port}/g" $dbdir/*.html + fi + #写入配置文件 + setconfig hostdir "'$hostdir'" + echo "-----------------------------------------------" + echo -e "\033[32m面板安装成功!\033[36m如未生效,请使用【Ctrl+F5】强制刷新浏览器!!!\033[0m" + rm -rf "$TMPDIR"/clashdb.tar.gz + fi + sleep 1 +} +setdb(){ + dbdir(){ + if [ -f /www/clash/CNAME -o -f "$CRASHDIR"/ui/CNAME ];then + echo "-----------------------------------------------" + echo -e "\033[31m检测到您已经安装过本地面板了!\033[0m" + echo "-----------------------------------------------" + read -p "是否升级/覆盖安装?[1/0] > " res + if [ "$res" = 1 ]; then + rm -rf "$BINDIR"/ui + [ -f /www/clash/CNAME ] && rm -rf /www/clash && dbdir=/www/clash + [ -f "$CRASHDIR"/ui/CNAME ] && rm -rf "$CRASHDIR"/ui && dbdir="$CRASHDIR"/ui + getdb + else + setdb + echo -e "\033[33m安装已取消!\033[0m" + fi + elif [ -w /www -a -n "$(pidof nginx)" ];then + echo "-----------------------------------------------" + echo -e "请选择面板\033[33m安装目录:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 在${CRASHDIR}/ui目录安装" + echo -e " 2 在/www/clash目录安装" + echo "-----------------------------------------------" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + + if [ "$num" = '1' ]; then + dbdir="$CRASHDIR"/ui + hostdir=":$db_port/ui" + getdb + elif [ "$num" = '2' ]; then + dbdir=/www/clash + hostdir='/clash' + getdb + else + setdb + echo -e "\033[33m安装已取消!\033[0m" + fi + else + dbdir="$CRASHDIR"/ui + hostdir=":$db_port/ui" + getdb + fi + } + + echo "-----------------------------------------------" + echo -e "\033[36m安装本地版dashboard管理面板\033[0m" + echo -e "\033[32m打开管理面板的速度更快且更稳定\033[0m" + echo "-----------------------------------------------" + echo -e "请选择面板\033[33m安装类型:\033[0m" + echo "-----------------维护中------------------------" + echo -e " 1 安装\033[32mzashboard面板\033[0m(约2.2mb)" + echo -e " 2 安装\033[32mMetaXD面板\033[0m(约1.5mb)" + echo -e " 3 安装\033[32mYacd-Meta魔改面板\033[0m(约1.7mb)" + echo "---------------已停止维护----------------------" + echo -e " 4 安装\033[32m基础面板\033[0m(约500kb)" + echo -e " 5 安装\033[32mMeta基础面板\033[0m(约800kb)" + echo -e " 6 安装\033[32mYacd面板\033[0m(约1.1mb)" + echo "-----------------------------------------------" + echo -e " 9 卸载\033[33m本地面板\033[0m" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + + case "$num" in + 0) ;; + 1) + db_type=zashboard + echo $update_url + setconfig external_ui_url "https://raw.githubusercontent.com/juewuy/ShellCrash/update/bin/dashboard/zashboard.tar.gz" + dbdir + ;; + 2) + db_type=meta_xd + setconfig external_ui_url "https://raw.githubusercontent.com/juewuy/ShellCrash/update/bin/dashboard/meta_xd.tar.gz" + dbdir + ;; + 3) + db_type=meta_yacd + dbdir + ;; + 4) + db_type=clashdb + dbdir + ;; + 5) + db_type=meta_db + dbdir + ;; + 6) + db_type=yacd + dbdir + ;; + 9) + read -p "确认卸载本地面板?(1/0) > " res + if [ "$res" = 1 ];then + rm -rf /www/clash + rm -rf "$CRASHDIR"/ui + rm -rf "$BINDIR"/ui + echo "-----------------------------------------------" + echo -e "\033[31m面板已经卸载!\033[0m" + sleep 1 + fi + ;; + *) + errornum + ;; + esac +} +#根证书 +getcrt(){ + echo "-----------------------------------------------" + echo "正在连接服务器获取安装文件…………" + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt + if [ "$?" = "1" ];then + echo "-----------------------------------------------" + echo -e "\033[31m文件下载失败!\033[0m" + error_down + else + echo "-----------------------------------------------" + [ "$systype" = 'mi_snapshot' ] && cp -f "$TMPDIR"/ca-certificates.crt $CRASHDIR/tools #镜像化设备特殊处理 + [ -f $openssldir/certs ] && rm -rf $openssldir/certs #如果certs不是目录而是文件则删除并创建目录 + mkdir -p $openssldir/certs + mv -f "$TMPDIR"/ca-certificates.crt $crtdir + "$CRASHDIR"/start.sh webget /dev/null https://baidu.com echooff rediron skipceroff + if [ "$?" = "1" ];then + export CURL_CA_BUNDLE=$crtdir + echo "export CURL_CA_BUNDLE=$crtdir" >> /etc/profile + fi + echo -e "\033[32m证书安装成功!\033[0m" + sleep 1 + fi +} +setcrt(){ + openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" + if [ -d "$openssldir/certs/" ];then + crtdir="$openssldir/certs/ca-certificates.crt" + else + crtdir="/etc/ssl/certs/ca-certificates.crt" + fi + if [ -n "$openssldir" ];then + echo "-----------------------------------------------" + echo -e "\033[36m安装/更新本地根证书文件(ca-certificates.crt)\033[0m" + echo -e "\033[33m用于解决证书校验错误,x509报错等问题\033[0m" + echo -e "\033[31m无上述问题的设备请勿使用!\033[0m" + echo "-----------------------------------------------" + [ -f "$crtdir" ] && echo -e "\033[33m检测到系统已经存在根证书文件($crtdir)了!\033[0m\n-----------------------------------------------" + read -p "是否覆盖更新?(1/0) > " res + + if [ -z "$res" ];then + errornum + elif [ "$res" = '0' ]; then + i= + elif [ "$res" = '1' ]; then + getcrt + else + errornum + fi + else + echo "-----------------------------------------------" + echo -e "\033[33m设备可能尚未安装openssl,无法安装证书文件!\033[0m" + sleep 1 + fi +} +#安装源 +setserver(){ + [ -z "$release_type" ] && release_name=未指定 + [ -n "$release_type" ] && release_name="$release_type(回退)" + [ "$release_type" = stable ] && release_name=稳定版 + [ "$release_type" = master ] && release_name=公测版 + [ "$release_type" = dev ] && release_name=开发版 + [ -n "$url_id" ] && url_name=$(grep "$url_id" "$CRASHDIR"/configs/servers.list 2>/dev/null | awk '{print $2}') || url_name="$update_url" + saveserver(){ + #写入配置文件 + setconfig update_url "'$update_url'" + setconfig url_id $url_id + setconfig release_type $release_type + echo "-----------------------------------------------" + echo -e "\033[32m源地址切换成功!\033[0m" + } + echo "-----------------------------------------------" + echo -e "\033[30;47m切换ShellCrash版本及更新源地址\033[0m" + echo -e "当前版本:\033[4;33m$release_name\033[0m 当前源:\033[4;32m$url_name\033[0m" + echo "-----------------------------------------------" + grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | awk '{print " "NR" "$2}' + echo "-----------------------------------------------" + echo -e " a 切换至\033[32m稳定版-stable\033[0m" + echo -e " b 切换至\033[36m公测版-master\033[0m" + echo -e " c 切换至\033[33m开发版-dev\033[0m" + echo "-----------------------------------------------" + echo -e " d 自定义源地址(用于本地源或自建源)" + echo -e " e \033[31m版本回退\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应字母或数字 > " num + case "$num" in + 0) + checkupdate=false + ;; + [1-99]) + url_id_new=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n ""$num"p" | awk '{print $1}') + if [ -z "$url_id_new" ];then + errornum + sleep 1 + setserver + elif [ "$url_id_new" -ge 200 ];then + update_url=$(grep -E "^1|$release_name" "$CRASHDIR"/configs/servers.list | sed -n ""$num"p" | awk '{print $3}') + url_id='' + saveserver + else + url_id=$url_id_new + update_url='' + saveserver + fi + unset url_id_new + ;; + a) + release_type=stable + [ -z "$url_id" ] && url_id=101 + saveserver + setserver + ;; + b) + release_type=master + [ -z "$url_id" ] && url_id=101 + saveserver + setserver + ;; + c) + echo "-----------------------------------------------" + echo -e "\033[33m开发版未经过妥善测试,可能依然存在大量bug!!!\033[0m" + echo -e "\033[36m如果你没有足够的耐心或者测试经验,切勿使用此版本!\033[0m" + echo -e "请务必加入我们的讨论组:\033[32;4mhttps://t.me/ShellClash\033[0m" + read -p "是否依然切换到开发版?(1/0) > " res + if [ "$res" = 1 ];then + release_type=dev + [ -z "$url_id" ] && url_id=101 + saveserver + fi + setserver + ;; + d) + echo "-----------------------------------------------" + read -p "请输入个人源路径 > " update_url + if [ -z "$update_url" ];then + echo "-----------------------------------------------" + echo -e "\033[31m取消输入,返回上级菜单\033[0m" + else + url_id='' + release_type='' + saveserver + fi + ;; + e) + echo "-----------------------------------------------" + if [ -n "$url_id" ] && [ "$url_id" -lt 200 ];then + echo -ne "\033[32m正在获取版本信息!\033[0m\r" + "$CRASHDIR"/start.sh get_bin "$TMPDIR"/release_version bin/release_version + if [ "$?" = "0" ];then + echo -e "\033[31m请选择想要回退至的稳定版版本:\033[0m" + cat "$TMPDIR"/release_version | awk '{print " "NR" "$1}' + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + if [ -z "$num" -o "$num" = 0 ]; then + setserver + elif [ $num -le $(cat "$TMPDIR"/release_version 2>/dev/null | awk 'END{print NR}') ]; then + release_type=$(cat "$TMPDIR"/release_version | awk '{print $1}' | sed -n "$num"p) + update_url='' + saveserver + else + echo "-----------------------------------------------" + errornum + sleep 1 + setserver + fi + else + echo "-----------------------------------------------" + echo -e "\033[31m版本回退信息获取失败,请尝试更换其他安装源!\033[0m" + sleep 1 + setserver + fi + rm -rf "$TMPDIR"/release_version + else + echo -e "\033[31m当前源不支持版本回退,请尝试更换其他安装源!\033[0m" + sleep 1 + setserver + fi + ;; + *) + errornum + ;; + esac +} diff --git a/scripts/start.sh b/scripts/start.sh index 3465fd70..77e0e239 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -10,6 +10,9 @@ CRASHDIR=$( . "$CRASHDIR"/configs/command.env >/dev/null 2>&1 [ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1 [ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR" +#加载工具 +. "$CRASHDIR"/libs/set_config.sh +. "$CRASHDIR"/libs/check_cmd.sh #脚本内部工具 getconfig() { #读取配置及全局变量 @@ -66,18 +69,7 @@ getconfig() { #读取配置及全局变量 } [ "$user_agent" = "none" ] && unset user_agent } -setconfig() { #脚本配置工具 - #参数1代表变量名,参数2代表变量值,参数3即文件路径 - [ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}" - if grep -q "^${1}=" "$configpath"; then - sed -i "s#^${1}=.*#${1}=${2}#g" "$configpath" - else - printf '%s=%s\n' "$1" "$2" >>"$configpath" - fi -} -ckcmd() { #检查命令是否存在 - command -v sh >/dev/null 2>&1 && command -v "$1" >/dev/null 2>&1 || type "$1" >/dev/null 2>&1 -} + ckgeo() { #查找及下载Geo数据文件 [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset find --help 2>&1 | grep -q size && find_para=' -size +20' #find命令兼容 diff --git a/scripts/webget.sh b/scripts/webget.sh index d8700df4..7e4b4389 100644 --- a/scripts/webget.sh +++ b/scripts/webget.sh @@ -11,1180 +11,6 @@ dir_avail(){ df $h $1 |awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' |grep -E 'Ava|可用' |awk '{print $2}' } -#导入订阅、配置文件相关 -setrules(){ #自定义规则 - set_rule_type(){ - echo "-----------------------------------------------" - echo -e "\033[33m请选择规则类型\033[0m" - echo $rule_type | awk -F ' ' '{for(i=1;i<=NF;i++){print i" "$i}}' - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - [0-9]*) - if [ $num -gt $(echo $rule_type | awk -F " " '{print NF}') ];then - errornum - else - rule_type_set=$(echo $rule_type|cut -d' ' -f$num) - echo "-----------------------------------------------" - echo -e "\033[33m请输入规则语句,可以是域名、泛域名、IP网段或者其他匹配规则类型的内容\033[0m" - read -p "请输入对应规则 > " rule_state_set - [ -n "$rule_state_set" ] && set_group_type || errornum - fi - ;; - *) - errornum - ;; - esac - } - set_group_type(){ - echo "-----------------------------------------------" - echo -e "\033[36m请选择具体规则\033[0m" - echo -e "\033[33m此处规则读取自现有配置文件,如果你后续更换配置文件时运行出错,请尝试重新添加\033[0m" - echo $rule_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - [0-9]*) - if [ $num -gt $(echo $rule_group | awk -F "#" '{print NF}') ];then - errornum - else - rule_group_set=$(echo $rule_group|cut -d'#' -f$num) - rule_all="- ${rule_type_set},${rule_state_set},${rule_group_set}" - [ -n "$(echo IP-CIDR SRC-IP-CIDR IP-CIDR6|grep "$rule_type_set")" ] && rule_all="${rule_all},no-resolve" - echo $rule_all >> $YAMLSDIR/rules.yaml - echo "-----------------------------------------------" - echo -e "\033[32m添加成功!\033[0m" - fi - ;; - *) - errornum - ;; - esac - } - del_rule_type(){ - echo -e "输入对应数字即可移除相应规则:" - sed -i '/^ *$/d; /^#/d' $YAMLSDIR/rules.yaml - cat $YAMLSDIR/rules.yaml | grep -Ev '^#' | awk -F "#" '{print " "NR" "$1$2$3}' - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - '') ;; - *) - if [ "$num" -le "$(wc -l < $YAMLSDIR/rules.yaml)" ];then - sed -i "${num}d" $YAMLSDIR/rules.yaml - sleep 1 - del_rule_type - else - errornum - fi - ;; - esac - } - get_rule_group(){ - "$CRASHDIR"/start.sh get_save http://127.0.0.1:${db_port}/proxies | sed 's/:{/!/g' | awk -F '!' '{for(i=1;i<=NF;i++) print $i}' | grep -aE '"Selector|URLTest|LoadBalance"' | grep -aoE '"name":.*"now":".*",' | awk -F '"' '{print "#"$4}' | tr -d '\n' - } - echo "-----------------------------------------------" - echo -e "\033[33m你可以在这里快捷管理自定义规则\033[0m" - echo -e "如需批量操作,请手动编辑:\033[36m $YAMLSDIR/rules.yaml\033[0m" - echo -e "\033[33msingbox和clash共用此处规则,可无缝切换!\033[0m" - echo -e "大量规则请尽量使用rule-set功能添加,\033[31m此处过量添加可能导致启动卡顿!\033[0m" - echo "-----------------------------------------------" - echo -e " 1 新增自定义规则" - echo -e " 2 移除自定义规则" - echo -e " 3 清空规则列表" - echo "$crashcore" | grep -q 'singbox' || echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - rule_type="DOMAIN-SUFFIX DOMAIN-KEYWORD IP-CIDR SRC-IP-CIDR DST-PORT SRC-PORT GEOIP GEOSITE IP-CIDR6 DOMAIN PROCESS-NAME" - rule_group="DIRECT#REJECT$(get_rule_group)" - set_rule_type - setrules - ;; - 2) - echo "-----------------------------------------------" - if [ -s $YAMLSDIR/rules.yaml ];then - del_rule_type - else - echo -e "请先添加自定义规则!" - sleep 1 - fi - setrules - ;; - 3) - read -p "确认清空全部自定义规则?(1/0) > " res - [ "$res" = "1" ] && sed -i '/^\s*[^#]/d' $YAMLSDIR/rules.yaml - setrules - ;; - 4) - echo "-----------------------------------------------" - if [ "$proxies_bypass" = "未启用" ];then - echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" - echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" - read -p "启用节点绕过?(1/0) > " res - [ "$res" = "1" ] && proxies_bypass=已启用 - else - proxies_bypass=未启用 - fi - setconfig proxies_bypass $proxies_bypass - sleep 1 - setrules - ;; - *) - errornum - ;; - esac -} -setgroups(){ #自定义clash策略组 - set_group_type(){ - echo "-----------------------------------------------" - echo -e "\033[33m注意策略组名称必须和【自定义规则】或【自定义节点】功能中指定的策略组一致!\033[0m" - echo -e "\033[33m建议先创建策略组,之后可在【自定义规则】或【自定义节点】功能中智能指定\033[0m" - echo -e "\033[33m如需在当前策略组下添加节点,请手动编辑$YAMLSDIR/proxy-groups.yaml\033[0m" - read -p "请输入自定义策略组名称(不支持纯数字且不要包含特殊字符!) > " new_group_name - echo "-----------------------------------------------" - echo -e "\033[32m请选择策略组【$new_group_name】的类型!\033[0m" - echo $group_type_cn | awk '{for(i=1;i<=NF;i++){print i" "$i}}' - read -p "请输入对应数字 > " num - new_group_type=$(echo $group_type | awk '{print $'"$num"'}') - if [ "$num" = "1" ];then - unset new_group_url interval - else - read -p "请输入测速地址,回车则默认使用https://www.gstatic.com/generate_204 > " new_group_url - [ -z "$new_group_url" ] && new_group_url=https://www.gstatic.com/generate_204 - new_group_url="url: '$new_group_url'" - interval="interval: 300" - fi - set_group_add - #添加自定义策略组 - cat >> $YAMLSDIR/proxy-groups.yaml < " char - case "$char" in - 0) ;; - *) - for num in $char;do - rule_group_set=$(echo $proxy_group|cut -d'#' -f$num) - rule_group_add="${rule_group_add}#${rule_group_set}" - done - if [ -n "$rule_group_add" ];then - new_group_name="$new_group_name$rule_group_add" - unset rule_group_add - else - errornum - fi - ;; - esac - } - echo "-----------------------------------------------" - echo -e "\033[33m你可以在这里快捷管理自定义策略组\033[0m" - echo -e "\033[36m如需修改或批量操作,请手动编辑:$YAMLSDIR/proxy-groups.yaml\033[0m" - echo "-----------------------------------------------" - echo -e " 1 添加自定义策略组" - echo -e " 2 查看自定义策略组" - echo -e " 3 清空自定义策略组" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - group_type="select url-test fallback load-balance" - group_type_cn="手动选择 自动选择 故障转移 负载均衡" - proxy_group="$(cat $YAMLSDIR/proxy-groups.yaml $YAMLSDIR/config.yaml 2>/dev/null | sed "/#自定义策略组开始/,/#自定义策略组结束/d" | grep -Ev '^#' | grep -o '\- name:.*' | sed 's/#.*//' | sed 's/- name: /#/g' | tr -d '\n' | sed 's/#//')" - set_group_type - setgroups - ;; - 2) - echo "-----------------------------------------------" - cat $YAMLSDIR/proxy-groups.yaml - setgroups - ;; - 3) - read -p "确认清空全部自定义策略组?(1/0) > " res - [ "$res" = "1" ] && echo '#用于添加自定义策略组' > $YAMLSDIR/proxy-groups.yaml - setgroups - ;; - *) - errornum - ;; - esac -} -setproxies(){ #自定义clash节点 - set_proxy_type(){ - echo "-----------------------------------------------" - echo -e "\033[33m注意节点格式必须是单行,不包括括号,name:必须写在最前,例如:\033[0m" - echo -e "\033[36m【name: \"test\", server: 192.168.1.1, port: 12345, type: socks5, udp: true】\033[0m" - echo -e "更多写法请参考:\033[32m https://juewuy.github.io/ \033[0m" - read -p "请输入节点 > " proxy_state_set - if [ -n "$(echo $proxy_state_set | grep "#" )" ];then - echo -e "\033[33m绝对禁止包含【#】号!!!\033[0m" - elif [ -n "$(echo $proxy_state_set | grep -E "^name:" )" ];then - set_group_add - else - errornum - fi - } - set_group_add(){ - echo "-----------------------------------------------" - echo -e "\033[36m请选择想要将节点添加到的策略组\033[0m" - echo -e "\033[32m如需添加到多个策略组,请一次性输入多个数字并用空格隔开\033[0m" - echo -e "\033[33m如需自定义策略组,请先使用【管理自定义策略组功能】添加\033[0m" - echo "-----------------------------------------------" - echo $proxy_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字(多个用空格隔开) > " char - case "$char" in - 0) ;; - *) - for num in $char;do - rule_group_set=$(echo $proxy_group|cut -d'#' -f$num) - rule_group_add="${rule_group_add}#${rule_group_set}" - done - if [ -n "$rule_group_add" ];then - echo "- {$proxy_state_set}$rule_group_add" >> $YAMLSDIR/proxies.yaml - echo "-----------------------------------------------" - echo -e "\033[32m添加成功!\033[0m" - unset rule_group_add - else - errornum - fi - ;; - esac - } - echo "-----------------------------------------------" - echo -e "\033[33m你可以在这里快捷管理自定义节点\033[0m" - echo -e "\033[36m如需批量操作,请手动编辑:$YAMLSDIR/proxies.yaml\033[0m" - echo "-----------------------------------------------" - echo -e " 1 添加自定义节点" - echo -e " 2 管理自定义节点" - echo -e " 3 清空自定义节点" - echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - proxy_type="DOMAIN-SUFFIX DOMAIN-KEYWORD IP-CIDR SRC-IP-CIDR DST-PORT SRC-PORT GEOIP GEOSITE IP-CIDR6 DOMAIN MATCH" - proxy_group="$(cat $YAMLSDIR/proxy-groups.yaml $YAMLSDIR/config.yaml 2>/dev/null | sed "/#自定义策略组开始/,/#自定义策略组结束/d" | grep -Ev '^#' | grep -o '\- name:.*' | sed 's/#.*//' | sed 's/- name: /#/g' | tr -d '\n' | sed 's/#//')" - set_proxy_type - setproxies - ;; - 2) - echo "-----------------------------------------------" - sed -i '/^ *$/d' $YAMLSDIR/proxies.yaml 2>/dev/null - if [ -s $YAMLSDIR/proxies.yaml ];then - echo -e "当前已添加的自定义节点为:" - cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | awk -F '[,,}]' '{print NR, $1, $NF}' | sed 's/- {//g' - echo "-----------------------------------------------" - echo -e "\033[33m输入节点对应数字可以移除对应节点\033[0m" - read -p "请输入对应数字 > " num - if [ $num -le $(cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | wc -l) ];then - sed -i "$num{/^\s*[^#]/d}" $YAMLSDIR/proxies.yaml - else - errornum - fi - else - echo -e "请先添加自定义节点!" - sleep 1 - fi - setproxies - ;; - 3) - read -p "确认清空全部自定义节点?(1/0) > " res - [ "$res" = "1" ] && sed -i '/^\s*[^#]/d' $YAMLSDIR/proxies.yaml 2>/dev/null - setproxies - ;; - 4) - echo "-----------------------------------------------" - if [ "$proxies_bypass" = "未启用" ];then - echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" - echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" - read -p "启用节点绕过?(1/0) > " res - [ "$res" = "1" ] && proxies_bypass=已启用 - else - proxies_bypass=未启用 - fi - setconfig proxies_bypass $proxies_bypass - sleep 1 - setrules - ;; - *) - errornum - ;; - esac -} -gen_clash_providers(){ #生成clash的providers配置文件 - gen_clash_providers_txt(){ - if [ -n "$(echo $2|grep -E '^./')" ];then - local type=file - local path=$2 - local download_url= - else - local type=http - local path="./providers/${1}.yaml" - local download_url=$2 - fi - cat >> $TMPDIR/providers/providers.yaml <> $TMPDIR/providers/providers.yaml < ${TMPDIR}/providers/providers.yaml - #切割模版文件 - sed -n '/^proxy-groups:/,/^[a-z]/ { /^rule/d; p; }' ${TMPDIR}/provider_temp_file > ${TMPDIR}/providers/proxy-groups.yaml - sed -n '/^rule/,$p' ${TMPDIR}/provider_temp_file > ${TMPDIR}/providers/rules.yaml - rm -rf ${TMPDIR}/provider_temp_file - #生成providers模块 - if [ -n "$2" ];then - gen_clash_providers_txt $1 $2 - providers_tags=$1 - echo ' - {name: '${1}', type: url-test, tolerance: 100, lazy: true, use: ['${1}']}' >> ${TMPDIR}/providers/proxy-groups.yaml - else - providers_tags='' - while read line;do - tag=$(echo $line | awk '{print $1}') - url=$(echo $line | awk '{print $2}') - providers_tags=$(echo "$providers_tags, $tag" | sed 's/^, //') - gen_clash_providers_txt $tag $url - echo ' - {name: '${tag}', type: url-test, tolerance: 100, lazy: true, use: ['${tag}']}' >> ${TMPDIR}/providers/proxy-groups.yaml - done < ${CRASHDIR}/configs/providers.cfg - fi - #修饰模版文件并合并 - sed -i "s/{providers_tags}/$providers_tags/g" ${TMPDIR}/providers/proxy-groups.yaml - cut -c 1- ${TMPDIR}/providers/providers.yaml ${TMPDIR}/providers/proxy-groups.yaml ${TMPDIR}/providers/rules.yaml > ${TMPDIR}/config.yaml - rm -rf ${TMPDIR}/providers - #调用内核测试 - ${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml - if [ "$?" = 0 ];then - echo -e "\033[32m配置文件生成成功!\033[0m" - mkdir -p ${CRASHDIR}/yamls - mv -f ${TMPDIR}/config.yaml ${CRASHDIR}/yamls/config.yaml - read -p "是否立即启动/重启服务?(1/0) > " res - [ "$res" = 1 ] && { - start_core && $CRASHDIR/start.sh cronset '更新订阅' - exit - } - else - rm -rf ${TMPDIR}/CrashCore - rm -rf ${TMPDIR}/config.yaml - echo -e "\033[31m生成配置文件出错,请仔细检查输入!\033[0m" - fi -} -gen_singbox_providers(){ #生成singbox的providers配置文件 - gen_singbox_providers_txt(){ - if [ -n "$(echo $2|grep -E '^./')" ];then - cat >> ${TMPDIR}/providers/providers.json <> ${TMPDIR}/providers/providers.json <> ${TMPDIR}/providers/providers.json < ${TMPDIR}/providers/providers.json < ${TMPDIR}/providers/outbounds_add.json <> ${TMPDIR}/providers/outbounds_add.json - else - providers_tags='' - while read line;do - tag=$(echo $line | awk '{print $1}') - url=$(echo $line | awk '{print $2}') - providers_tags=$(echo "$providers_tags, \"$tag\"" | sed 's/^, //') - gen_singbox_providers_txt $tag $url - echo '{ "tag": "'${tag}'", "type": "urltest", "tolerance": 100, "providers": ["'${tag}'"], "include": ".*" },' >> ${TMPDIR}/providers/outbounds_add.json - done < ${CRASHDIR}/configs/providers.cfg - fi - #修复文件格式 - sed -i '$s/},/}]}/' ${TMPDIR}/providers/outbounds_add.json - sed -i '$s/},/}]}/' ${TMPDIR}/providers/providers.json - #使用模版生成outbounds和rules模块 - cat ${TMPDIR}/provider_temp_file | sed "s/{providers_tags}/$providers_tags/g" > ${TMPDIR}/providers/outbounds.json - rm -rf ${TMPDIR}/provider_temp_file - #调用内核测试 - ${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore merge ${TMPDIR}/config.json -C ${TMPDIR}/providers - if [ "$?" = 0 ];then - echo -e "\033[32m配置文件生成成功!如果启动超时建议更新里手动安装Singbox-srs数据库常用包!\033[0m" - mkdir -p ${CRASHDIR}/jsons - mv -f ${TMPDIR}/config.json ${CRASHDIR}/jsons/config.json - rm -rf ${TMPDIR}/providers - read -p "是否立即启动/重启服务?(1/0) > " res - [ "$res" = 1 ] && { - start_core && $CRASHDIR/start.sh cronset '更新订阅' - exit - } - else - echo -e "\033[31m生成配置文件出错,请仔细检查输入!\033[0m" - rm -rf ${TMPDIR}/CrashCore - rm -rf ${TMPDIR}/providers - fi -} -setproviders(){ #自定义providers - #获取模版名称 - if [ -z "$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg)" ];then - provider_temp_des=$(sed -n "1 p" ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print $1}') - else - provider_temp_file=$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg | awk -F '=' '{print $2}') - provider_temp_des=$(grep "$provider_temp_file" ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print $1}') - [ -z "$provider_temp_des" ] && provider_temp_des=$provider_temp_file - fi - echo "-----------------------------------------------" - echo -e "\033[33m你可以在这里快捷管理与生成自定义的providers服务商\033[0m" - echo -e "\033[33m支持在线及本地的Yaml格式配置导入\033[0m" - [ -s $CRASHDIR/configs/providers.cfg ] && { - echo "-----------------------------------------------" - echo -e "\033[36m输入对应数字可管理providers服务商\033[0m" - cat $CRASHDIR/configs/providers.cfg | awk -F "#" '{print " "NR" "$1" "$2}' - } - echo -e " d \033[31m清空\033[0mproviders服务商列表" - echo -e " e \033[33m清理\033[0mproviders目录文件" - echo "-----------------------------------------------" - echo -e "\033[36m按照a-b-c的顺序即可完成配置生成\033[0m" - echo -e " a \033[36m添加\033[0mproviders服务商/节点" - echo -e " b 选择\033[33m规则模版\033[0m \033[32m$provider_temp_des\033[0m" - echo -e " c \033[32m生成\033[0m基于providers的配置文件" - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单" - read -p "请输入对应字母或数字 > " num - case "$num" in - 0) - ;; - [1-9]|[1-9][0-9]) - provider_name=$(sed -n "$num p" $CRASHDIR/configs/providers.cfg | awk '{print $1}') - provider_url=$(sed -n "$num p" $CRASHDIR/configs/providers.cfg | awk '{print $2}') - if [ -z "$provider_name" ];then - errornum - else - echo "-----------------------------------------------" - echo -e " 1 修改名称:\033[36m$provider_name\033[0m" - echo -e " 2 修改链接地址:\033[32m$provider_url\033[0m" - echo -e " 3 生成\033[33m仅包含此链接\033[0m的配置文件" - echo -e " 4 \033[31m移除此链接\033[0m" - echo "-----------------------------------------------" - echo -e " 0 返回上级菜单" - read -p "请选择需要执行的操作 > " num - case "$num" in - 0) - ;; - 1) - read -p "请输入名称或者代号(不可重复,不支持纯数字) > " name - if [ -n "$name" ] && [ -z "$(echo "$name" | grep -E '^[0-9]+$')" ] && ! grep -q "$name" $CRASHDIR/configs/providers.cfg;then - sed -i "s|$provider_name $provider_url|$name $provider_url|" $CRASHDIR/configs/providers.cfg - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - ;; - 2) - read -p "请输入链接地址或本地相对路径 > " link - if [ -n "$(echo $link | grep -E '.*\..*|^\./')" ] && [ -z "$(grep "$link" $CRASHDIR/configs/providers.cfg)" ];then - link=$(echo $link | sed 's/\&/\\\&/g') #特殊字符添加转义 - sed -i "s|$provider_name $provider_url|$provider_name $link|" $CRASHDIR/configs/providers.cfg - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - ;; - 3) - gen_${coretype}_providers $provider_name $provider_url - ;; - 4) - sed -i "/^$provider_name /d" $CRASHDIR/configs/providers.cfg - ;; - *) - errornum - ;; - esac - sleep 1 - fi - setproviders - ;; - a) - echo "-----------------------------------------------" - echo -e "支持填写在线的\033[32mYClash订阅地址\033[0m或者\033[32m本地Clash配置文件\033[0m" - echo -e "本地配置文件请放在\033[32m$CRASHDIR\033[0m目录下,并填写相对路径如【\033[32m./providers/test.yaml\033[0m】" - echo "-----------------------------------------------" - read -p "请输入链接地址或本地相对路径 > " link - link=$(echo $link | sed 's/ //g') #去空格 - [ -n "$(echo $link | grep -E '.*\..*|^\./')" ] && { - read -p "请输入名称或代号(不可重复,不支持纯数字) > " name - name=$(echo $name | sed 's/ //g') - [ -n "$name" ] && [ -z "$(echo "$name" | grep -E '^[0-9]+$')" ] && ! grep -q "$name" $CRASHDIR/configs/providers.cfg && { - echo "-----------------------------------------------" - echo -e "名称:\033[36m$name\033[0m" - echo -e "链接地址/路径:\033[32m$link\033[0m" - read -p "确认添加?(1/0) > " res - [ "$res" = 1 ] && { - echo "$name $link" >> $CRASHDIR/configs/providers.cfg - echo -e "\033[32mproviders已添加!\033[0m" - } - } - } - [ "$?" != 0 ] && echo -e "\033[31m输入错误,操作已取消!\033[0m" - sleep 1 - setproviders - ;; - c) - echo "-----------------------------------------------" - if [ -s $CRASHDIR/configs/providers.cfg ];then - echo -e "\033[33msingboxr与mihomo内核的providers配置文件不互通!\033[0m" - echo "-----------------------------------------------" - read -p "确认生成${coretype}配置文件?(1/0) > " res - [ "$res" = "1" ] && { - gen_${coretype}_providers - } - else - echo -e "\033[31m你还未添加链接或本地配置文件,请先添加!\033[0m" - sleep 1 - fi - setproviders - ;; - b) - echo "-----------------------------------------------" - echo -e "当前规则模版为:\033[32m$provider_temp_des\033[0m" - echo -e "\033[33m请选择在线模版:\033[0m" - echo "-----------------------------------------------" - cat ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print " "NR" "$1}' - echo "-----------------------------------------------" - echo -e " a 使用\033[36m本地模版\033[0m" - echo "-----------------------------------------------" - read -p "请输入对应字母或数字 > " num - case "$num" in - 0) - ;; - a) - read -p "请输入模版的路径(绝对路径) > " dir - if [ -s $dir ];then - provider_temp_file=$dir - setconfig provider_temp_${coretype} $provider_temp_file - echo -e "\033[32m设置成功!\033[0m" - else - echo -e "\033[31m输入错误,找不到对应模版文件!\033[0m" - fi - sleep 1 - ;; - *) - provider_temp_file=$(sed -n "$num p" ${CRASHDIR}/configs/${coretype}_providers.list 2>/dev/null | awk '{print $2}') - if [ -z "$provider_temp_file" ];then - errornum - else - setconfig provider_temp_${coretype} $provider_temp_file - fi - ;; - esac - setproviders - ;; - d) - read -p "确认清空全部链接?(1/0) > " res - [ "$res" = "1" ] && rm -rf $CRASHDIR/configs/providers.cfg - setproviders - ;; - e) - echo -e "\033[33m将清空 $CRASHDIR/providers 目录下所有内容\033[0m" - read -p "是否继续?(1/0) > " res - [ "$res" = "1" ] && rm -rf $CRASHDIR/providers - setproviders - ;; - *) - errornum - ;; - esac -} - -set_clash_adv(){ #自定义clash高级规则 - [ ! -f $YAMLSDIR/user.yaml ] && cat > $YAMLSDIR/user.yaml < $YAMLSDIR/others.yaml < " num - case "$num" in - 0) - ;; - 1) - if [ -n "$(pidof CrashCore)" ];then - echo "-----------------------------------------------" - echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" - read -p "是否停止服务?(1/0) > " res - if [ "$res" = "1" ];then - ${CRASHDIR}/start.sh stop - setport - fi - else - setport - fi - override - ;; - 2) - setrules - override - ;; - 3) - setproxies - override - ;; - 4) - setgroups - override - ;; - 5) - echo "$crashcore" | grep -q 'singbox' && set_singbox_adv || set_clash_adv - sleep 3 - override - ;; - 9) - echo "-----------------------------------------------" - echo -e "\033[33m此功能可能会导致严重问题!启用后脚本中大部分功能都将禁用!!!\033[0m" - echo -e "如果你不是非常了解$crashcore的运行机制,切勿开启!\033[0m" - echo -e "\033[33m继续后如出现任何问题,请务必自行解决,一切提问恕不受理!\033[0m" - echo "-----------------------------------------------" - sleep 2 - read -p "我确认遇到问题可以自行解决[1/0] > " res - [ "$res" = '1' ] && { - disoverride=1 - setconfig disoverride $disoverride - echo "-----------------------------------------------" - echo -e "\033[32m设置成功!\033[0m" - } - override - ;; - *) - errornum - ;; - esac -} - -gen_link_config(){ #选择在线规则 - echo "-----------------------------------------------" - echo 当前使用规则为:$(grep -aE '^5' ${CRASHDIR}/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $2}') - grep -aE '^5' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$2$4}' - echo "-----------------------------------------------" - echo 0 返回上级菜单 - read -p "请输入对应数字 > " num - totalnum=$(grep -acE '^5' ${CRASHDIR}/configs/servers.list ) - if [ -z "$num" ] || [ "$num" -gt "$totalnum" ];then - errornum - elif [ "$num" = 0 ];then - echo - elif [ "$num" -le "$totalnum" ];then - #将对应标记值写入配置 - rule_link=$num - setconfig rule_link $rule_link - echo "-----------------------------------------------" - echo -e "\033[32m设置成功!返回上级菜单\033[0m" - fi -} -gen_link_server(){ #选择在线服务器 - echo "-----------------------------------------------" - echo -e "\033[36m以下为互联网采集的第三方服务器,具体安全性请自行斟酌!\033[0m" - echo -e "\033[32m感谢以下作者的无私奉献!!!\033[0m" - echo 当前使用后端为:$(grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}') - grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$3" "$2}' - echo "-----------------------------------------------" - echo 0 返回上级菜单 - read -p "请输入对应数字 > " num - totalnum=$(grep -acE '^3|^4' ${CRASHDIR}/configs/servers.list ) - if [ -z "$num" ] || [ "$num" -gt "$totalnum" ];then - errornum - elif [ "$num" = 0 ];then - echo - elif [ "$num" -le "$totalnum" ];then - #将对应标记值写入配置 - server_link=$num - setconfig server_link $server_link - echo "-----------------------------------------------" - echo -e "\033[32m设置成功!返回上级菜单\033[0m" - fi -} -gen_link_flt(){ #在线生成节点过滤 - [ -z "$exclude" ] && exclude="未设置" - echo "-----------------------------------------------" - echo -e "\033[33m当前过滤关键字:\033[47;30m$exclude\033[0m" - echo "-----------------------------------------------" - echo -e "\033[33m匹配关键字的节点会在导入时被【屏蔽】!!!\033[0m" - echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" - echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" - echo "-----------------------------------------------" - echo -e " 000 \033[31m删除\033[0m关键字" - echo -e " 回车 取消输入并返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入关键字 > " exclude - if [ "$exclude" = '000' ]; then - echo "-----------------------------------------------" - exclude='' - echo -e "\033[31m 已删除节点过滤关键字!!!\033[0m" - fi - setconfig exclude "'$exclude'" -} -gen_link_ele(){ #在线生成节点筛选 - [ -z "$include" ] && include="未设置" - echo "-----------------------------------------------" - echo -e "\033[33m当前筛选关键字:\033[47;30m$include\033[0m" - echo "-----------------------------------------------" - echo -e "\033[33m仅有匹配关键字的节点才会被【导入】!!!\033[0m" - echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" - echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" - echo "-----------------------------------------------" - echo -e " 000 \033[31m删除\033[0m关键字" - echo -e " 回车 取消输入并返回上级菜单" - echo "-----------------------------------------------" - read -p "请输入关键字 > " include - if [ "$include" = '000' ]; then - echo "-----------------------------------------------" - include='' - echo -e "\033[31m 已删除节点匹配关键字!!!\033[0m" - fi - setconfig include "'$include'" -} -get_core_config(){ #调用工具下载 - ${CRASHDIR}/start.sh get_core_config - if [ "$?" = 0 ];then - if [ "$inuserguide" != 1 ];then - read -p "是否启动服务以使配置文件生效?(1/0) > " res - [ "$res" = 1 ] && start_core || main_menu - exit; - fi - fi -} -gen_core_config_link(){ #在线生成工具 - echo "-----------------------------------------------" - echo -e "\033[30;47m 欢迎使用在线生成配置文件功能!\033[0m" - echo "-----------------------------------------------" - #设置输入循环 - i=1 - while [ $i -le 99 ] - do - echo "-----------------------------------------------" - echo -e "\033[33m本功能依赖第三方在线subconverter服务实现,脚本本身不提供任何代理服务!\033[0m" - echo -e "\033[31m严禁使用本脚本从事任何非法活动,否则一切后果请自负!\033[0m" - echo "-----------------------------------------------" - echo -e "支持批量(<=99)导入订阅链接、分享链接" - echo "-----------------------------------------------" - echo -e " 1 \033[36m开始生成配置文件\033[0m(原文件将被备份)" - echo -e " 2 设置\033[31m节点过滤\033[0m关键字 \033[47;30m$exclude\033[0m" - echo -e " 3 设置\033[32m节点筛选\033[0m关键字 \033[47;30m$include\033[0m" - echo -e " 4 选取在线\033[33m配置规则模版\033[0m" - echo -e " 5 \033[0m选取在线生成服务器\033[0m" - echo -e " 0 \033[31m撤销输入并返回上级菜单\033[0m" - echo "-----------------------------------------------" - read -p "请直接输入第${i}个链接或对应数字选项 > " link - link=$(echo $link | sed 's/\&/%26/g') #处理分隔符 - test=$(echo $link | grep "://") - link=`echo ${link/\#*/''}` #删除链接附带的注释内容 - link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 - link=`echo ${link/*\&url\=/""}` #将完整链接还原成单一链接 - link=`echo ${link/\&config\=*/""}` #将完整链接还原成单一链接 - - if [ -n "$test" ];then - if [ -z "$Url_link" ];then - Url_link="$link" - else - Url_link="$Url_link"\|"$link" - fi - i=$((i+1)) - - elif [ "$link" = '1' ]; then - if [ -n "$Url_link" ];then - i=100 - #将用户链接写入配置 - setconfig Https - setconfig Url "'$Url_link'" - #获取在线yaml文件 - get_core_config - else - echo "-----------------------------------------------" - echo -e "\033[31m请先输入订阅或分享链接!\033[0m" - sleep 1 - fi - - elif [ "$link" = '2' ]; then - gen_link_flt - - elif [ "$link" = '3' ]; then - gen_link_ele - - elif [ "$link" = '4' ]; then - gen_link_config - - elif [ "$link" = '5' ]; then - gen_link_server - - elif [ "$link" = 0 ];then - Url_link="" - i=100 - - else - echo "-----------------------------------------------" - echo -e "\033[31m请输入正确的链接或者数字!\033[0m" - sleep 1 - fi - done -} -set_core_config_link(){ #直接导入配置 - echo "-----------------------------------------------" - echo -e "\033[32m仅限导入完整的配置文件链接!!!\033[0m" - echo "-----------------------------------------------" - echo -e "注意:\033[31m此功能不兼容“跳过证书验证”功能,部分老旧\n设备可能出现x509报错导致节点不通\033[0m" - echo -e "你也可以搭配在线订阅转换网站或者自建SubStore使用" - echo "$crashcore" | grep -q 'singbox' &&echo -e "singbox内核建议使用\033[32;4mhttps://subv.jwsc.eu.org/\033[0m转换" - echo "-----------------------------------------------" - echo -e "\033[33m0 返回上级菜单\033[0m" - echo "-----------------------------------------------" - read -p "请输入完整链接 > " link - test=$(echo $link | grep -iE "tp.*://" ) - link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 - link=`echo ${link//\&/\\\&}` #处理分隔符 - if [ -n "$link" -a -n "$test" ];then - echo "-----------------------------------------------" - echo -e 请检查输入的链接是否正确: - echo -e "\033[4;32m$link\033[0m" - read -p "确认导入配置文件?原配置文件将被备份![1/0] > " res - if [ "$res" = '1' ]; then - #将用户链接写入配置 - sed -i '/Url=*/'d $CFG_PATH - setconfig Https "'$link'" - setconfig Url - #获取在线yaml文件 - get_core_config - else - set_core_config_link - fi - elif [ "$link" = 0 ];then - i= - else - echo "-----------------------------------------------" - echo -e "\033[31m请输入正确的配置文件链接地址!!!\033[0m" - echo -e "\033[33m仅支持http、https、ftp以及ftps链接!\033[0m" - sleep 1 - set_core_config_link - fi -} -set_core_config(){ #配置文件功能 - [ -z "$rule_link" ] && rule_link=1 - [ -z "$server_link" ] && server_link=1 - echo "$crashcore" | grep -q 'singbox' && config_path=${JSONSDIR}/config.json || config_path=${YAMLSDIR}/config.yaml - echo "-----------------------------------------------" - echo -e "\033[30;47m ShellCrash配置文件管理\033[0m" - echo "-----------------------------------------------" - echo -e " 1 在线\033[32m生成配置文件\033[0m(基于Subconverter订阅转换)" - if [ -f "$CRASHDIR"/v2b_api.sh ];then - echo -e " 2 登录\033[33m获取订阅(推荐!)\033[0m" - else - echo -e " 2 在线\033[33m获取配置文件\033[0m(基于订阅提供者)" - fi - echo -e " 3 本地\033[32m生成配置文件\033[0m(基于内核providers,推荐!)" - echo -e " 4 本地\033[33m上传完整配置文件\033[0m" - echo -e " 5 设置\033[36m自动更新\033[0m" - echo -e " 6 \033[32m自定义\033[0m配置文件" - echo -e " 7 \033[33m更新\033[0m配置文件" - echo -e " 8 \033[36m还原\033[0m配置文件" - echo -e " 9 自定义浏览器UA \033[32m$user_agent\033[0m" - echo "-----------------------------------------------" - [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - if [ -n "$Url" ];then - echo "-----------------------------------------------" - echo -e "\033[33m检测到已记录的链接内容:\033[0m" - echo -e "\033[4;32m$Url\033[0m" - echo "-----------------------------------------------" - read -p "清空链接/追加导入?[1/0] > " res - if [ "$res" = '1' ]; then - Url_link="" - echo "-----------------------------------------------" - echo -e "\033[31m链接已清空!\033[0m" - else - Url_link=$Url - fi - fi - gen_core_config_link - set_core_config - ;; - 2) - if [ -f "$CRASHDIR"/v2b_api.sh ];then - . "$CRASHDIR"/v2b_api.sh - set_core_config - else - set_core_config_link - fi - set_core_config - ;; - 3) - if [ "$crashcore" = meta -o "$crashcore" = clashpre ];then - coretype=clash - setproviders - elif [ "$crashcore" = singboxr ];then - coretype=singbox - setproviders - else - echo -e "\033[33msingbox官方内核及Clash基础内核不支持此功能,请先更换内核!\033[0m" - sleep 1 - checkupdate && setcore - fi - set_core_config - ;; - 4) - echo "-----------------------------------------------" - echo -e "\033[33m请将本地配置文件上传到/tmp目录并重命名为config.yaml或者config.json\033[0m" - echo -e "\033[32m之后重新运行本脚本即可自动弹出导入提示!\033[0m" - exit - ;; - 5) - . ${CRASHDIR}/task/task.sh && task_menu - set_core_config - ;; - 6) - checkcfg=$(cat $CFG_PATH) - override - if [ -n "$PID" ];then - checkcfg_new=$(cat $CFG_PATH) - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - set_core_config - ;; - 7) - if [ -z "$Url" -a -z "$Https" ];then - echo "-----------------------------------------------" - echo -e "\033[31m没有找到你的配置文件/订阅链接!请先输入链接!\033[0m" - sleep 1 - set_core_config - else - echo "-----------------------------------------------" - echo -e "\033[33m当前系统记录的链接为:\033[0m" - echo -e "\033[4;32m$Url$Https\033[0m" - echo "-----------------------------------------------" - read -p "确认更新配置文件?[1/0] > " res - if [ "$res" = '1' ]; then - get_core_config - else - set_core_config - fi - fi - ;; - 8) - if [ ! -f ${config_path}.bak ];then - echo "-----------------------------------------------" - echo -e "\033[31m没有找到配置文件的备份!\033[0m" - set_core_config - else - echo "-----------------------------------------------" - echo -e 备份文件共有"\033[32m`wc -l < ${config_path}.bak`\033[0m"行内容,当前文件共有"\033[32m`wc -l < ${config_path}`\033[0m"行内容 - read -p "确认还原配置文件?此操作不可逆![1/0] > " res - if [ "$res" = '1' ]; then - mv ${config_path}.bak ${config_path} - echo "----------------------------------------------" - echo -e "\033[32m配置文件已还原!请手动重启服务!\033[0m" - sleep 1 - else - echo "-----------------------------------------------" - echo -e "\033[31m操作已取消!返回上级菜单!\033[0m" - set_core_config - fi - fi - ;; - 9) - echo "-----------------------------------------------" - echo -e "\033[36m如果6-1或者6-2无法正确获取配置文件时可以尝试使用\033[0m" - echo -e " 1 使用自动UA" - echo -e " 2 不使用UA" - echo -e " 3 使用自定义UA:\033[32m$user_agent\033[0m" - echo "-----------------------------------------------" - read -p "请输入对应数字 > " num - case "$num" in - 0) - user_agent='' - ;; - 1) - user_agent='auto' - ;; - 2) - user_agent='none' - ;; - 3) - read -p "请输入自定义UA(不要包含空格和特殊符号!) > " text - [ -n "$text" ] && user_agent="$text" - ;; - *) - errornum - ;; - esac - [ "$num" -le 3 ] && setconfig user_agent "$user_agent" - set_core_config - ;; - *) - errornum - ;; - esac -} #下载更新相关 getscripts(){ #更新脚本文件 ${CRASHDIR}/start.sh get_bin ${TMPDIR}/ShellCrash.tar.gz ShellCrash.tar.gz @@ -1802,12 +628,12 @@ setgeo(){ #数据库选择菜单 read -p "确认清理?[1/0] > " res [ "$res" = '1' ] && { for file in cn_ip.txt cn_ipv6.txt Country.mmdb GeoSite.dat geoip.db geosite.db;do - rm -rf $CRASHDIR/$file + rm -rf "$CRASHDIR"/$file done for var in Country_v cn_mini_v china_ip_list_v china_ipv6_list_v geosite_v geoip_cn_v geosite_cn_v mrs_geosite_cn_v srs_geoip_cn_v srs_geosite_cn_v mrs_v srs_v;do setconfig $var done - rm -rf $CRASHDIR/ruleset/* + rm -rf "$CRASHDIR"/ruleset/* echo -e "\033[33m所有数据库文件均已清理!\033[0m" sleep 1 } @@ -1971,7 +797,7 @@ getcrt(){ #下载根证书文件 error_down else echo "-----------------------------------------------" - [ "$systype" = 'mi_snapshot' ] && cp -f ${TMPDIR}/ca-certificates.crt $CRASHDIR/tools #镜像化设备特殊处理 + [ "$systype" = 'mi_snapshot' ] && cp -f ${TMPDIR}/ca-certificates.crt "$CRASHDIR"/tools #镜像化设备特殊处理 [ -f $openssldir/certs ] && rm -rf $openssldir/certs #如果certs不是目录而是文件则删除并创建目录 mkdir -p $openssldir/certs mv -f ${TMPDIR}/ca-certificates.crt $crtdir @@ -2405,7 +1231,7 @@ userguide(){ [ "$res" = 1 ] && autoSSH fi #提示导入订阅或者配置文件 - [ ! -s $CRASHDIR/yamls/config.yaml -a ! -s $CRASHDIR/jsons/config.json ] && { + [ ! -s "$CRASHDIR"/yamls/config.yaml -a ! -s "$CRASHDIR"/jsons/config.json ] && { echo "-----------------------------------------------" echo -e "\033[32m是否导入配置文件?\033[0m(这是运行前的最后一步)" echo -e "\033[0m你必须拥有一份配置文件才能运行服务!\033[0m" @@ -2431,7 +1257,7 @@ userguide(){ } #测试菜单 debug(){ - echo "$crashcore" | grep -q 'singbox' && config_tmp=$TMPDIR/jsons || config_tmp=$TMPDIR/config.yaml + echo "$crashcore" | grep -q 'singbox' && config_tmp="$TMPDIR"/jsons || config_tmp="$TMPDIR"/config.yaml echo "-----------------------------------------------" echo -e "\033[36m注意:Debug运行均会停止原本的内核服务\033[0m" echo -e "后台运行日志地址:\033[32m$TMPDIR/debug.log\033[0m" @@ -2446,17 +1272,17 @@ debug(){ echo -e " 6 后台运行完整启动流程,并配置防火墙劫持,且将错误日志打印到闪存:\033[32m$CRASHDIR/debug.log\033[0m" echo "-----------------------------------------------" echo -e " 8 后台运行完整启动流程,输出执行错误并查找上下文,之后关闭进程" - [ -s $TMPDIR/jsons/inbounds.json ] && echo -e " 9 将\033[32m$config_tmp\033[0m下json文件合并为$TMPDIR/debug.json" + [ -s "$TMPDIR"/jsons/inbounds.json ] && echo -e " 9 将\033[32m$config_tmp\033[0m下json文件合并为$TMPDIR/debug.json" echo "-----------------------------------------------" echo " 0 返回上级目录!" read -p "请输入对应数字 > " num case "$num" in 0) ;; 1) - $CRASHDIR/start.sh stop - $CRASHDIR/start.sh bfstart + "$CRASHDIR"/start.sh stop + "$CRASHDIR"/start.sh bfstart if echo "$crashcore" | grep -q 'singbox' ;then - $TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons & + "$TMPDIR"/CrashCore run -D "$BINDIR" -C "$TMPDIR"/jsons & { sleep 4 ; kill $! >/dev/null 2>&1 & } wait else @@ -2467,29 +1293,29 @@ debug(){ exit ;; 2) - $CRASHDIR/start.sh stop - $CRASHDIR/start.sh bfstart + "$CRASHDIR"/start.sh stop + "$CRASHDIR"/start.sh bfstart $COMMAND rm -rf ${TMPDIR}/CrashCore echo "-----------------------------------------------" exit ;; 3) - $CRASHDIR/start.sh debug error + "$CRASHDIR"/start.sh debug error main_menu ;; 4) - $CRASHDIR/start.sh debug info + "$CRASHDIR"/start.sh debug info main_menu ;; 5) - $CRASHDIR/start.sh debug debug + "$CRASHDIR"/start.sh debug debug main_menu ;; 6) echo -e "频繁写入闪存会导致闪存寿命降低,如非遇到会导致设备死机或重启的bug,请勿使用此功能!" read -p "是否继续?(1/0) > " res - [ "$res" = 1 ] && $CRASHDIR/start.sh debug debug flash + [ "$res" = 1 ] && "$CRASHDIR"/start.sh debug debug flash main_menu ;; 8) @@ -2497,7 +1323,7 @@ debug(){ main_menu ;; 9) - ${CRASHDIR}/start.sh core_check && $TMPDIR/CrashCore merge $TMPDIR/debug.json -C $TMPDIR/jsons && echo -e "\033[32m合并成功!\033[0m" + ${CRASHDIR}/start.sh core_check && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && echo -e "\033[32m合并成功!\033[0m" rm -rf ${TMPDIR}/CrashCore main_menu ;;