From 647b52e0166f1a9396944ba57907097d202a4877 Mon Sep 17 00:00:00 2001 From: juewuy Date: Thu, 25 Dec 2025 15:50:58 +0800 Subject: [PATCH] =?UTF-8?q?~=E8=84=9A=E6=9C=AC=E8=BF=9B=E8=A1=8C=E5=A4=A7?= =?UTF-8?q?=E9=87=8F=E6=8B=86=E5=88=86=E5=92=8C=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/task.list | 6 +- scripts/init.sh | 292 ++--- scripts/libs/check_cpucore.sh | 14 + scripts/libs/check_target.sh | 8 + scripts/libs/core_tools.sh | 80 ++ scripts/libs/get_config.sh | 11 + scripts/libs/logger.sh | 1 + scripts/libs/set_cron.sh | 27 + scripts/libs/set_profile.sh | 8 + scripts/libs/set_proxy.sh | 2 +- scripts/libs/start_wait.sh | 10 + scripts/libs/urlencode.sh | 15 + scripts/libs/web_get.sh | 40 +- scripts/libs/web_restore.sh | 20 + scripts/libs/web_save.sh | 30 + scripts/menu.sh | 41 +- scripts/menus/1_start.sh | 11 +- scripts/menus/2_settings.sh | 68 +- scripts/menus/5_task.sh | 279 +---- scripts/menus/6_core_config.sh | 14 +- scripts/menus/8_tools.sh | 6 +- scripts/menus/9_upgrade.sh | 126 +-- scripts/menus/dns.sh | 1 + scripts/menus/set_crashdir.sh | 149 +++ scripts/start.sh | 1385 +----------------------- scripts/starts/afstart.sh | 58 + scripts/starts/bfstart.sh | 136 +++ scripts/starts/check_cnip.sh | 24 + scripts/starts/check_core.sh | 18 + scripts/starts/check_geo.sh | 16 + scripts/starts/check_network.sh | 11 + scripts/starts/clash_check.sh | 21 + scripts/starts/clash_config_check.sh | 41 + scripts/starts/clash_modify.sh | 236 ++++ scripts/starts/core_config.sh | 103 ++ scripts/starts/core_exchange.sh | 11 + scripts/starts/fw_getlanip.sh | 27 + scripts/starts/fw_iptables.sh | 2 + scripts/starts/fw_start.sh | 83 +- scripts/starts/fw_stop.sh | 258 ++--- scripts/starts/general_init.sh | 34 + scripts/starts/shellcrash.openrc | 73 -- scripts/starts/shellcrash.procd | 38 - scripts/starts/shellcrash.service | 20 - scripts/starts/singbox_check.sh | 13 + scripts/starts/singbox_config_check.sh | 37 + scripts/starts/singbox_modify.sh | 387 +++++++ scripts/starts/snapshot_init.sh | 94 -- scripts/starts/start_error.sh | 12 + 49 files changed, 1948 insertions(+), 2449 deletions(-) create mode 100644 scripts/libs/check_cpucore.sh create mode 100644 scripts/libs/check_target.sh create mode 100644 scripts/libs/core_tools.sh create mode 100644 scripts/libs/get_config.sh create mode 100644 scripts/libs/set_cron.sh create mode 100644 scripts/libs/set_profile.sh create mode 100644 scripts/libs/start_wait.sh create mode 100644 scripts/libs/urlencode.sh create mode 100644 scripts/libs/web_restore.sh create mode 100644 scripts/libs/web_save.sh create mode 100644 scripts/menus/set_crashdir.sh create mode 100644 scripts/starts/afstart.sh create mode 100644 scripts/starts/bfstart.sh create mode 100644 scripts/starts/check_cnip.sh create mode 100644 scripts/starts/check_core.sh create mode 100644 scripts/starts/check_geo.sh create mode 100644 scripts/starts/check_network.sh create mode 100644 scripts/starts/clash_check.sh create mode 100644 scripts/starts/clash_config_check.sh create mode 100644 scripts/starts/clash_modify.sh create mode 100644 scripts/starts/core_config.sh create mode 100644 scripts/starts/core_exchange.sh create mode 100644 scripts/starts/fw_getlanip.sh create mode 100644 scripts/starts/general_init.sh delete mode 100644 scripts/starts/shellcrash.openrc delete mode 100644 scripts/starts/shellcrash.procd delete mode 100644 scripts/starts/shellcrash.service create mode 100644 scripts/starts/singbox_check.sh create mode 100644 scripts/starts/singbox_config_check.sh create mode 100644 scripts/starts/singbox_modify.sh delete mode 100644 scripts/starts/snapshot_init.sh create mode 100644 scripts/starts/start_error.sh diff --git a/public/task.list b/public/task.list index f8bbe00c..40f5ad2b 100644 --- a/public/task.list +++ b/public/task.list @@ -3,9 +3,9 @@ 101#$CRASHDIR/start.sh start#启动ShellCrash服务 102#$CRASHDIR/start.sh stop#停止ShellCrash服务 103#$CRASHDIR/start.sh restart#重启ShellCrash服务 -104#$CRASHDIR/start.sh update_config#更新在线订阅并重启服务 -105#$CRASHDIR/start.sh hotupdate#热更新在线订阅(不重启) -106#$CRASHDIR/start.sh web_save#自动保存面板配置 +104#$CRASHDIR/task/task.sh update_config#更新在线订阅并重启服务 +105#$CRASHDIR/task/task.sh hotupdate#热更新在线订阅(不重启) +106#$CRASHDIR/task/task.sh web_save_auto#自动保存面板配置 107#$CRASHDIR/task/task.sh ntp#自动同步ntp时间 111#$CRASHDIR/task/task.sh update_core#自动更新内核 diff --git a/scripts/init.sh b/scripts/init.sh index 3bd03a2b..c7e0f286 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -1,161 +1,6 @@ #!/bin/sh # Copyright (C) Juewuy -setdir() { - dir_avail() { - df $2 $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}' - } - set_usb_dir() { - echo -e "请选择安装目录" - du -hL /mnt | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) - if [ -z "$dir" ]; then - echo -e "\033[31m输入错误!请重新设置!\033[0m" - set_usb_dir - fi - } - set_asus_dir() { - echo -e "请选择U盘目录" - du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p) - if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then - echo -e "\033[31m未找到下载大师自启文件:$dir/asusware.arm/etc/init.d/S50downloadmaster,请检查设置!\033[0m" - set_asus_dir - fi - } - set_cust_dir() { - echo "-----------------------------------------------" - echo "可用路径 剩余空间:" - df -h | awk '{print $6,$4}' | sed 1d - echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!" - read -p "请输入自定义路径 > " dir - if [ "$(dir_avail $dir)" = 0 ] || [ -n "$(echo $dir | grep -E 'tmp|opt|sys')" ]; then - echo "\033[31m路径错误!请重新设置!\033[0m" - set_cust_dir - fi - } - echo "-----------------------------------------------" - if [ -n "$systype" ]; then - [ "$systype" = "Padavan" ] && dir=/etc/storage - [ "$systype" = "mi_snapshot" ] && { - echo -e "\033[33m检测到当前设备为小米官方系统,请选择安装位置\033[0m" - [ -d /data ] && $echo " 1 安装到 /data 目录,剩余空间:$(dir_avail /data -h)(支持软固化功能)" - [ -d /userdisk ] && $echo " 2 安装到 /userdisk 目录,剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)" - [ -d /data/other_vol ] && $echo " 3 安装到 /data/other_vol 目录,剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)" - $echo " 4 安装到自定义目录(不推荐,不明勿用!)" - echo " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num - case "$num" in - 1) - dir=/data - ;; - 2) - dir=/userdisk - ;; - 3) - dir=/data/other_vol - ;; - 4) - set_cust_dir - ;; - *) - exit 1 - ;; - esac - } - [ "$systype" = "asusrouter" ] && { - echo -e "\033[33m检测到当前设备为华硕固件,请选择安装方式\033[0m" - echo -e " 1 基于USB设备安装(限23年9月之前固件,须插入\033[31m任意\033[0mUSB设备)" - echo -e " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)" - echo -e " 3 基于U盘+下载大师安装(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" - echo -e " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num - case "$num" in - 1) - read -p "将脚本安装到USB存储/系统闪存?(1/0) > " res - [ "$res" = "1" ] && set_usb_dir || dir=/jffs - usb_status=1 - ;; - 2) - echo -e "如无法正常开机启动,请重新使用USB方式安装!" - sleep 2 - dir=/jffs - ;; - 3) - echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!" - sleep 2 - set_asus_dir - ;; - *) - exit 1 - ;; - esac - } - [ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt - else - echo -e "\033[33m安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m" - echo -e " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)" - echo -e " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)" - echo -e " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)" - echo -e " 4 在\033[32m外置存储\033[0m中安装" - echo -e " 5 手动设置安装目录" - echo -e " 0 退出安装" - echo "-----------------------------------------------" - read -p "请输入相应数字 > " num - #设置目录 - case "$num" in - 1) - dir=/etc - ;; - 2) - dir=/usr/share - ;; - 3) - dir=~/.local/share - mkdir -p ~/.config/systemd/user - ;; - 4) - set_usb_dir - ;; - 5) - echo "-----------------------------------------------" - echo "可用路径 剩余空间:" - df -h | awk '{print $6,$4}' | sed 1d - echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!" - read -p "请输入自定义路径 > " dir - if [ -z "$dir" ]; then - echo -e "\033[31m路径错误!请重新设置!\033[0m" - setdir - fi - ;; - *) - echo "安装已取消" - exit 1 - ;; - esac - fi - - if [ ! -w $dir ]; then - echo -e "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir - else - echo -e "目标目录\033[32m$dir\033[0m空间剩余:$(dir_avail $dir -h)" - read -p "确认安装?(1/0) > " res - [ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir - fi -} -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 -} #特殊固件识别及标记 [ -f "/etc/storage/started_script.sh" ] && { #老毛子固件 systype=Padavan @@ -176,20 +21,25 @@ grep -qE '/(docker|lxc|kubepods|crio|containerd)/' /proc/1/cgroup || [ -f /run/. #检查环境变量 [ "$systype" = 'container' ] && CRASHDIR='/etc/ShellCrash' [ -z "$CRASHDIR" ] && [ -n "$clashdir" ] && CRASHDIR="$clashdir" -[ -z "$CRASHDIR" ] && [ -d /tmp/SC_tmp ] && setdir +[ -z "$CRASHDIR" ] && [ -d /tmp/SC_tmp ] && . /tmp/SC_tmp/menus/set_crashdir.sh && set_crashdir #移动文件 -mkdir -p ${CRASHDIR} -mv -f /tmp/SC_tmp/* ${CRASHDIR} 2>/dev/null - +mkdir -p "$CRASHDIR" +rm -rf /tmp/SC_tmp/menus/set_crashdir.sh +mv -f /tmp/SC_tmp/* "$CRASHDIR" 2>/dev/null +############################## +#注意目录变更 +CFG_PATH="$CRASHDIR"/configs/ShellCrash.cfg +. "$CRASHDIR"/libs/set_config.sh +. "$CRASHDIR"/libs/set_profile.sh #初始化 -mkdir -p ${CRASHDIR}/configs -[ -f "${CRASHDIR}/configs/ShellCrash.cfg" ] || echo '#ShellCrash配置文件,不明勿动!' >${CRASHDIR}/configs/ShellCrash.cfg +mkdir -p "$CRASHDIR"/configs +[ -f "$CFG_PATH" ] || echo '#ShellCrash配置文件,不明勿动!' >"$CFG_PATH" #判断系统类型写入不同的启动文件 [ -w /usr/lib/systemd/system ] && sysdir=/usr/lib/systemd/system [ -w /etc/systemd/system ] && sysdir=/etc/systemd/system if [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then #设为init.d方式启动 - cp -f ${CRASHDIR}/starts/shellcrash.procd /etc/init.d/shellcrash + cp -f "$CRASHDIR"/starts/shellcrash.procd /etc/init.d/shellcrash chmod 755 /etc/init.d/shellcrash elif [ -n "$sysdir" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then #创建shellcrash用户 @@ -203,45 +53,45 @@ elif [ -n "$sysdir" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; echo "shellcrash:x:0:7890::/home/shellcrash:/bin/sh" >>/etc/passwd fi #配置systemd - mv -f ${CRASHDIR}/starts/shellcrash.service $sysdir/shellcrash.service 2>/dev/null - sed -i "s%/etc/ShellCrash%$CRASHDIR%g" $sysdir/shellcrash.service + mv -f "$CRASHDIR"/starts/shellcrash.service "$sysdir"/shellcrash.service 2>/dev/null + sed -i "s%/etc/ShellCrash%$CRASHDIR%g" "$sysdir"/shellcrash.service systemctl daemon-reload - rm -rf ${CRASHDIR}/starts/shellcrash.procd + rm -rf "$CRASHDIR"/starts/shellcrash.procd elif rc-status -r >/dev/null 2>&1; then #设为openrc方式启动 - mv -f ${CRASHDIR}/starts/shellcrash.openrc /etc/init.d/shellcrash + mv -f "$CRASHDIR"/starts/shellcrash.openrc /etc/init.d/shellcrash chmod 755 /etc/init.d/shellcrash - rm -rf ${CRASHDIR}/starts/shellcrash.procd + rm -rf "$CRASHDIR"/starts/shellcrash.procd else #设为保守模式启动 setconfig start_old 已开启 - rm -rf ${CRASHDIR}/starts/shellcrash.procd + rm -rf "$CRASHDIR"/starts/shellcrash.procd fi -rm -rf ${CRASHDIR}/starts/shellcrash.service -rm -rf ${CRASHDIR}/starts/shellcrash.openrc +rm -rf "$CRASHDIR"/starts/shellcrash.service +rm -rf "$CRASHDIR"/starts/shellcrash.openrc #修饰文件及版本号 command -v bash >/dev/null 2>&1 && shtype=bash [ -x /bin/ash ] && shtype=ash -for file in start.sh menus/5-task.sh menu.sh; do - sed -i "s|/bin/sh|/bin/$shtype|" ${CRASHDIR}/${file} 2>/dev/null - chmod +x ${CRASHDIR}/${file} 2>/dev/null +for file in start.sh starts/bfstart.sh starts/afstart.sh menu.sh menus/task_cmd.sh; do + sed -i "s|/bin/sh|/bin/$shtype|" "$CRASHDIR/$file" 2>/dev/null + chmod +x "$CRASHDIR/$file" 2>/dev/null done setconfig versionsh_l $version #生成用于执行启动服务的变量文件 -[ ! -f ${CRASHDIR}/configs/command.env ] && { +[ ! -f "$CRASHDIR"/configs/command.env ] && { TMPDIR='/tmp/ShellCrash' - BINDIR=${CRASHDIR} - touch ${CRASHDIR}/configs/command.env - setconfig TMPDIR ${TMPDIR} ${CRASHDIR}/configs/command.env - setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env + BINDIR="$CRASHDIR" + touch "$CRASHDIR"/configs/command.env + setconfig TMPDIR "$TMPDIR" "$CRASHDIR"/configs/command.env + setconfig BINDIR "$BINDIR" "$CRASHDIR"/configs/command.env } -if [ -n "$(grep 'crashcore=singbox' ${CRASHDIR}/configs/ShellCrash.cfg)" ]; then +if [ -n "$(grep 'crashcore=singbox' "$CFG_PATH")" ]; 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 +setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env #设置防火墙执行模式 grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { firewall_mod=iptables @@ -254,13 +104,6 @@ grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { [ -w /opt/etc/profile ] && profile=/opt/etc/profile [ -w /jffs/configs/profile.add ] && profile=/jffs/configs/profile.add [ -z "$profile" ] && profile=/etc/profile -set_profile() { - [ -z "$my_alias" ] && my_alias=crash - sed -i "/ShellCrash\/menu.sh/"d "$1" - echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量 - sed -i '/export CRASHDIR=*/'d "$1" - echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量 -} if [ -n "$profile" ]; then set_profile "$profile" #适配zsh环境变量 @@ -272,17 +115,18 @@ else fi #梅林/Padavan额外设置 [ -n "$initdir" ] && { - sed -i '/ShellCrash初始化/'d $initdir - touch $initdir - echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >>$initdir - chmod a+rx $initdir 2>/dev/null - setconfig initdir $initdir + touch "$initdir" + sed -i '/ShellCrash初始化/'d "$initdir" + echo "$CRASHDIR/starts/general_init.sh & #ShellCrash初始化脚本" >>"$initdir" + chmod 755 "$CRASHDIR"/starts/general_init.sh + chmod a+rx "$initdir" 2>/dev/null + setconfig initdir "$initdir" } #Padavan额外设置 [ -f "/etc/storage/started_script.sh" ] && mount -t tmpfs -o remount,rw,size=45M tmpfs /tmp #增加/tmp空间以适配新的内核压缩方式 #镜像化OpenWrt(snapshot)额外设置 if [ "$systype" = "mi_snapshot" -o "$systype" = "ng_snapshot" ]; then - chmod 755 ${CRASHDIR}/starts/snapshot_init.sh + chmod 755 "$CRASHDIR"/starts/snapshot_init.sh uci delete firewall.ShellClash 2>/dev/null uci delete firewall.ShellCrash 2>/dev/null uci set firewall.ShellCrash=include @@ -291,11 +135,11 @@ if [ "$systype" = "mi_snapshot" -o "$systype" = "ng_snapshot" ]; then uci set firewall.ShellCrash.enabled='1' uci commit firewall else - rm -rf ${CRASHDIR}/starts/snapshot_init.sh + rm -rf "$CRASHDIR"/starts/snapshot_init.sh fi #华硕USB启动额外设置 [ "$usb_status" = "1" ] && { - echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >${CRASHDIR}/asus_usb_mount.sh + echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >"$CRASHDIR"/asus_usb_mount.sh nvram set script_usbmount="$CRASHDIR/asus_usb_mount.sh" nvram commit } @@ -325,57 +169,57 @@ setconfig systype $systype rm -rf /tmp/*rash*gz rm -rf /tmp/SC_tmp #转换&清理旧版本文件 -mkdir -p ${CRASHDIR}/yamls -mkdir -p ${CRASHDIR}/jsons -mkdir -p ${CRASHDIR}/tools -mkdir -p ${CRASHDIR}/task -mkdir -p ${CRASHDIR}/ruleset +mkdir -p "$CRASHDIR"/yamls +mkdir -p "$CRASHDIR"/jsons +mkdir -p "$CRASHDIR"/tools +mkdir -p "$CRASHDIR"/task +mkdir -p "$CRASHDIR"/ruleset for file in config.yaml.bak user.yaml proxies.yaml proxy-groups.yaml rules.yaml others.yaml; do - mv -f ${CRASHDIR}/$file ${CRASHDIR}/yamls/$file 2>/dev/null + mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/yamls/"$file" 2>/dev/null done -[ ! -L ${CRASHDIR}/config.yaml ] && mv -f ${CRASHDIR}/config.yaml ${CRASHDIR}/yamls/config.yaml 2>/dev/null +[ ! -L "$CRASHDIR"/config.yaml ] && mv -f "$CRASHDIR"/config.yaml "$CRASHDIR"/yamls/config.yaml 2>/dev/null for file in fake_ip_filter mac web_save servers.list fake_ip_filter.list fallback_filter.list singbox_providers.list clash_providers.list; do - mv -f ${CRASHDIR}/$file ${CRASHDIR}/configs/$file 2>/dev/null + mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/configs/"$file" 2>/dev/null done #配置文件改名 -mv -f ${CRASHDIR}/configs/ShellClash.cfg ${CRASHDIR}/configs/ShellCrash.cfg 2>/dev/null +mv -f "$CRASHDIR"/configs/ShellClash.cfg "$CFG_PATH" 2>/dev/null #数据库改名 -mv -f ${CRASHDIR}/geosite.dat ${CRASHDIR}/GeoSite.dat 2>/dev/null -mv -f ${CRASHDIR}/ruleset/geosite-cn.srs ${CRASHDIR}/ruleset/cn.srs 2>/dev/null -mv -f ${CRASHDIR}/ruleset/geosite-cn.mrs ${CRASHDIR}/ruleset/cn.mrs 2>/dev/null +mv -f "$CRASHDIR"/geosite.dat "$CRASHDIR"/GeoSite.dat 2>/dev/null +mv -f "$CRASHDIR"/ruleset/geosite-cn.srs "$CRASHDIR"/ruleset/cn.srs 2>/dev/null +mv -f "$CRASHDIR"/ruleset/geosite-cn.mrs "$CRASHDIR"/ruleset/cn.mrs 2>/dev/null #数据库移动 -mv -f ${CRASHDIR}/*.srs ${CRASHDIR}/ruleset/ 2>/dev/null -mv -f ${CRASHDIR}/*.mrs ${CRASHDIR}/ruleset/ 2>/dev/null +mv -f "$CRASHDIR"/*.srs "$CRASHDIR"/ruleset/ 2>/dev/null +mv -f "$CRASHDIR"/*.mrs "$CRASHDIR"/ruleset/ 2>/dev/null #内核改名 -mv -f ${CRASHDIR}/clash ${CRASHDIR}/CrashCore 2>/dev/null +mv -f "$CRASHDIR"/clash "$CRASHDIR"/CrashCore 2>/dev/null #内核压缩 -[ -f ${CRASHDIR}/CrashCore ] && tar -zcf ${CRASHDIR}/CrashCore.tar.gz -C ${CRASHDIR} CrashCore +[ -f "$CRASHDIR"/CrashCore ] && tar -zcf "$CRASHDIR"/CrashCore.tar.gz -C "$CRASHDIR" CrashCore for file in dropbear_rsa_host_key authorized_keys tun.ko ShellDDNS.sh; do - mv -f ${CRASHDIR}/$file ${CRASHDIR}/tools/$file 2>/dev/null + mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/tools/"$file" 2>/dev/null done for file in cron task.list; do - mv -f ${CRASHDIR}/$file ${CRASHDIR}/task/$file 2>/dev/null + mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/task/"$file" 2>/dev/null done +mv -f "$CRASHDIR"/menus/task_cmd.sh "$CRASHDIR"/task/task.sh 2>/dev/null #旧版文件清理 userdel shellclash >/dev/null 2>&1 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" +rm -rf "$CRASHDIR"/rules [ "$systype" = "mi_snapshot" -a "$CRASHDIR" != '/data/clash' ] && rm -rf /data/clash for file in CrashCore clash.sh getdate.sh core.new clashservice log mark? mark.bak; do rm -rf "$CRASHDIR/$file" done #旧版变量改名 -sed -i "s/clashcore/crashcore/g" $configpath -sed -i "s/clash_v/core_v/g" $configpath -sed -i "s/clash.meta/meta/g" $configpath -sed -i "s/ShellClash/ShellCrash/g" $configpath -sed -i "s/cpucore=armv8/cpucore=arm64/g" $configpath -sed -i "s/redir_mod=Nft基础/redir_mod=Redir模式/g" $configpath -sed -i "s/redir_mod=Nft混合/redir_mod=Tproxy模式/g" $configpath -sed -i "s/redir_mod=Tproxy混合/redir_mod=Tproxy模式/g" $configpath -sed -i "s/redir_mod=纯净模式/firewall_area=4/g" $configpath +sed -i "s/clashcore/crashcore/g" "$CFG_PATH" +sed -i "s/clash_v/core_v/g" "$CFG_PATH" +sed -i "s/clash.meta/meta/g" "$CFG_PATH" +sed -i "s/ShellClash/ShellCrash/g" "$CFG_PATH" +sed -i "s/cpucore=armv8/cpucore=arm64/g" "$CFG_PATH" +sed -i "s/redir_mod=Nft基础/redir_mod=Redir模式/g" "$CFG_PATH" +sed -i "s/redir_mod=Nft混合/redir_mod=Tproxy模式/g" "$CFG_PATH" +sed -i "s/redir_mod=Tproxy混合/redir_mod=Tproxy模式/g" "$CFG_PATH" +sed -i "s/redir_mod=纯净模式/firewall_area=4/g" "$CFG_PATH" echo -e "\033[32m脚本初始化完成,请输入\033[30;47m $my_alias \033[0;33m命令开始使用!\033[0m" diff --git a/scripts/libs/check_cpucore.sh b/scripts/libs/check_cpucore.sh new file mode 100644 index 00000000..cae95fee --- /dev/null +++ b/scripts/libs/check_cpucore.sh @@ -0,0 +1,14 @@ + +check_cpucore(){ #自动获取内核架构 + 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 +} diff --git a/scripts/libs/check_target.sh b/scripts/libs/check_target.sh new file mode 100644 index 00000000..b8efc811 --- /dev/null +++ b/scripts/libs/check_target.sh @@ -0,0 +1,8 @@ +if echo "$crashcore" | grep -q 'singbox'; then + target=singbox + format=json +else + target=clash + format=yaml +fi +core_config="$CRASHDIR/${format}s/config.$format" diff --git a/scripts/libs/core_tools.sh b/scripts/libs/core_tools.sh new file mode 100644 index 00000000..536b2b00 --- /dev/null +++ b/scripts/libs/core_tools.sh @@ -0,0 +1,80 @@ + + +[ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容 + +core_unzip() { #$1:需要解压的文件 $2:目标文件名 + if echo "$1" |grep -q 'tar.gz$' ;then + [ "$BINDIR" = "$TMPDIR" ] && rm -rf "$TMPDIR"/CrashCore #小闪存模式防止空间不足 + [ -n "$(tar --help 2>&1 | grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容 + mkdir -p "$TMPDIR"/core_tmp + tar -zxf "$1" ${tar_para} -C "$TMPDIR"/core_tmp/ + for file in $(find "$TMPDIR"/core_tmp $find_para 2>/dev/null); do + [ -f "$file" ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|pre)')" ] && mv -f "$file" "$TMPDIR"/"$2" + done + rm -rf "$TMPDIR"/core_tmp + elif echo "$1" |grep -q '.gz$' ;then + gunzip -c "$1" > "$TMPDIR"/"$2" + elif echo "$1" |grep -q '.upx$' ;then + ln -sf "$1" "$TMPDIR"/"$2" + else + mv -f "$1" "$TMPDIR"/"$2" + fi + chmod +x "$TMPDIR"/"$2" +} +core_find(){ + if [ ! -f "$TMPDIR"/CrashCore ];then + core_dir=$(find "$BINDIR"/CrashCore.* $find_para 2>/dev/null) + [ -n "$core_dir" ] && core_unzip "$core_dir" CrashCore + fi +} +core_check(){ + [ -n "$(pidof CrashCore)" ] && "$CRASHDIR"/start.sh stop #停止内核服务防止内存不足 + core_unzip "$1" core_new + sbcheck=$(echo "$crashcore" | grep 'singbox') + v='' + if [ -n "$sbcheck" ] && "$TMPDIR"/core_new -h 2>&1 | grep -q 'sing-box'; then + v=$("$TMPDIR"/core_new version 2>/dev/null | grep version | awk '{print $3}') + COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' + elif [ -z "$sbcheck" ] && "$TMPDIR"/core_new -h 2>&1 | grep -q '\-t';then + v=$("$TMPDIR"/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') + COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' + fi + if [ -z "$v" ]; then + rm -rf "$TMPDIR"/core_new + rm -rf "$1" + return 2 + else + rm -f "$BINDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.gz "$BINDIR"/CrashCore.upx + mv -f "$TMPDIR"/core_new "$TMPDIR"/CrashCore + if [ -f "$1" ];then + mv -f "$1" "$BINDIR/CrashCore.${zip_type}" + else + gzip -c "$TMPDIR"/CrashCore > "$BINDIR"/CrashCore.gz + fi + core_v="$v" + setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env && . "$CRASHDIR"/configs/command.env + setconfig crashcore "$crashcore" + setconfig core_v "$core_v" + setconfig custcorelink "$custcorelink" + return 0 + fi +} +core_webget(){ + . "$CRASHDIR"/libs/web_get_bin.sh + . "$CRASHDIR"/libs/check_target.sh + if [ -z "$custcorelink" ];then + [ -z "$zip_type" ] && zip_type='tar.gz' + get_bin "$TMPDIR/CrashCore.${zip_type}" "bin/$crashcore/${target}-linux-${cpucore}.${zip_type}" + else + zip_type=$(echo "$custcorelink" | grep -oE 'tar.gz$') + [ -z "$zip_type" ] && zip_type=$(echo "$custcorelink" | grep -oE 'gz$') + [ -n "$zip_type" ] && webget "$TMPDIR/CrashCore.${zip_type}" "$custcorelink" + fi + #校验内核 + if [ "$?" = 0 ];then + core_check "$TMPDIR/CrashCore.${zip_type}" + else + rm -rf "$TMPDIR/CrashCore.${zip_type}" + return 1 + fi +} diff --git a/scripts/libs/get_config.sh b/scripts/libs/get_config.sh new file mode 100644 index 00000000..84af3781 --- /dev/null +++ b/scripts/libs/get_config.sh @@ -0,0 +1,11 @@ +. "$CRASHDIR"/configs/command.env >/dev/null 2>&1 +. "$CRASHDIR"/configs/ShellCrash.cfg + +[ -z "$mix_port" ] && mix_port=7890 +[ -z "$redir_port" ] && redir_port=7892 +[ -z "$tproxy_port" ] && tproxy_port=7893 +[ -z "$db_port" ] && db_port=9999 +[ -z "$dns_port" ] && dns_port=1053 +[ -z "$fwmark" ] && fwmark=$redir_port +routing_mark=$((fwmark + 2)) +[ -z "$table" ] && table=100 diff --git a/scripts/libs/logger.sh b/scripts/libs/logger.sh index 7044586b..19efd221 100644 --- a/scripts/libs/logger.sh +++ b/scripts/libs/logger.sh @@ -1,6 +1,7 @@ #日志工具 #$1日志内容$2显示颜色$3是否推送 logger() { + TMPDIR=/tmp/ShellCrash [ -n "$2" -a "$2" != 0 ] && echo -e "\033[$2m$1\033[0m" log_text="$(date "+%G-%m-%d_%H:%M:%S")~$1" echo "$log_text" >>"$TMPDIR"/ShellCrash.log diff --git a/scripts/libs/set_cron.sh b/scripts/libs/set_cron.sh new file mode 100644 index 00000000..6bbb2869 --- /dev/null +++ b/scripts/libs/set_cron.sh @@ -0,0 +1,27 @@ + +croncmd() { #定时任务工具 + if [ -n "$(crontab -h 2>&1 | grep '\-l')" ]; then + crontab "$1" + else + crondir="$(crond -h 2>&1 | grep -oE 'Default:.*' | awk -F ":" '{print $2}')" + [ ! -w "$crondir" ] && crondir="/etc/storage/cron/crontabs" + [ ! -w "$crondir" ] && crondir="/var/spool/cron/crontabs" + [ ! -w "$crondir" ] && crondir="/var/spool/cron" + if [ -w "$crondir" ]; then + [ "$1" = "-l" ] && cat "$crondir"/"$USER" 2>/dev/null + [ -f "$1" ] && cat "$1" >"$crondir"/"$USER" + else + echo "找不到可用的crond或者crontab应用!No available crond or crontab application can be found!" + fi + fi +} +cronset() { #定时任务设置 + # 参数1代表要移除的关键字,参数2代表要添加的任务语句 + tmpcron="$TMPDIR"/cron_tmp + croncmd -l >"$tmpcron" 2>/dev/null + sed -i "/$1/d" "$tmpcron" + sed -i '/^$/d' "$tmpcron" + echo "$2" >>"$tmpcron" + croncmd "$tmpcron" + rm -f "$tmpcron" +} diff --git a/scripts/libs/set_profile.sh b/scripts/libs/set_profile.sh new file mode 100644 index 00000000..2bf2790e --- /dev/null +++ b/scripts/libs/set_profile.sh @@ -0,0 +1,8 @@ + +set_profile() { + [ -z "$my_alias" ] && my_alias=crash + sed -i "/ShellCrash\/menu.sh/"d "$1" + echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量 + sed -i '/export CRASHDIR=*/'d "$1" + echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量 +} \ No newline at end of file diff --git a/scripts/libs/set_proxy.sh b/scripts/libs/set_proxy.sh index ce32d02e..3f3400cf 100644 --- a/scripts/libs/set_proxy.sh +++ b/scripts/libs/set_proxy.sh @@ -3,6 +3,6 @@ setproxy(){ [ -n "$(pidof CrashCore)" ] && { [ -n "$authentication" ] && auth="$authentication@" || auth="" [ -z "$mix_port" ] && mix_port=7890 - export https_proxy="http://${auth}127.0.0.1:$mix_port" + export all_proxy="http://${auth}127.0.0.1:$mix_port" } } \ No newline at end of file diff --git a/scripts/libs/start_wait.sh b/scripts/libs/start_wait.sh new file mode 100644 index 00000000..ffbee612 --- /dev/null +++ b/scripts/libs/start_wait.sh @@ -0,0 +1,10 @@ +i=1 +while [ -z "$test" -a "$i" -lt 30 ]; do + sleep 1 + if curl --version >/dev/null 2>&1; then + test=$(curl -s -H "Authorization: Bearer $secret" http://127.0.0.1:${db_port}/proxies | grep -o proxies) + else + test=$(wget -q --header="Authorization: Bearer $secret" -O - http://127.0.0.1:${db_port}/proxies | grep -o proxies) + fi + i=$((i + 1)) +done diff --git a/scripts/libs/urlencode.sh b/scripts/libs/urlencode.sh new file mode 100644 index 00000000..abf4e8d8 --- /dev/null +++ b/scripts/libs/urlencode.sh @@ -0,0 +1,15 @@ +urlencode() { + LC_ALL=C + printf '%s' "$1" \ + | hexdump -v -e '/1 "%02X\n"' \ + | while read -r hex; do + case "$hex" in + 2D|2E|5F|7E|3[0-9]|4[1-9A-F]|5[0-9A]|6[1-9A-F]|7[0-9A-E]) + printf "\\$(printf '%03o' "0x$hex")" + ;; + *) + printf "%%%s" "$hex" + ;; + esac + done +} \ No newline at end of file diff --git a/scripts/libs/web_get.sh b/scripts/libs/web_get.sh index d68e3105..949fd6d9 100644 --- a/scripts/libs/web_get.sh +++ b/scripts/libs/web_get.sh @@ -3,43 +3,43 @@ webget(){ if pidof CrashCore >/dev/null; then setproxy #设置临时代理 - url=$(printf '%s\n' "$3" | + url=$(printf '%s\n' "$2" | sed -e 's#https://.*jsdelivr.net/gh/juewuy/ShellCrash[@|/]#https://raw.githubusercontent.com/juewuy/ShellCrash/#' \ -e 's#https://gh.jwsc.eu.org/#https://raw.githubusercontent.com/juewuy/ShellCrash/#') else - url=$(printf '%s\n' "$3" | + url=$(printf '%s\n' "$2" | sed 's#https://raw.githubusercontent.com/juewuy/ShellCrash/#https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@#') fi - #参数【$2】代表下载目录,【$3】代表在线地址 - #参数【$4】代表输出显示,【$5】不启用重定向 - #参数【$6】代表验证证书,【$7】使用自定义UA - [ -n "$7" ] && agent="--user-agent \"$7\"" + #参数【$1】代表下载目录,【$2】代表在线地址 + #参数【$3】代表输出显示,【$4】不启用重定向 + #参数【$5】代表验证证书,【$6】使用自定义UA + [ -n "$6" ] && agent="--user-agent \"$6\"" if wget --help 2>&1 | grep -q 'show-progress' >/dev/null 2>&1; then - [ "$4" = "echooff" ] && progress='-q' || progress='-q --show-progress' - [ "$5" = "rediroff" ] && redirect='--max-redirect=0' || redirect='' - [ "$6" = "skipceroff" ] && certificate='' || certificate='--no-check-certificate' - wget -Y on $agent $progress $redirect $certificate --timeout=3 -O "$2" "$url" && return 0 #成功则退出否则重试 - wget -Y off $agent $progress $redirect $certificate --timeout=5 -O "$2" "$3" + [ "$3" = "echooff" ] && progress='-q' || progress='-q --show-progress' + [ "$4" = "rediroff" ] && redirect='--max-redirect=0' || redirect='' + [ "$5" = "skipceroff" ] && certificate='' || certificate='--no-check-certificate' + wget -Y on $agent $progress $redirect $certificate --timeout=3 -O "$1" "$url" && return 0 #成功则退出否则重试 + wget -Y off $agent $progress $redirect $certificate --timeout=5 -O "$1" "$2" return $? elif curl --version >/dev/null 2>&1; then - [ "$4" = "echooff" ] && progress='-s' || progress='-#' - [ "$5" = "rediroff" ] && redirect='' || redirect='-L' - [ "$6" = "skipceroff" ] && certificate='' || certificate='-k' + [ "$3" = "echooff" ] && progress='-s' || progress='-#' + [ "$4" = "rediroff" ] && redirect='' || redirect='-L' + [ "$5" = "skipceroff" ] && certificate='' || certificate='-k' if curl --version | grep -q '^curl 8.' && ckcmd base64; then auth_b64=$(printf '%s' "$authentication" | base64) - result=$(curl $agent -w '%{http_code}' --connect-timeout 3 --proxy-header "Proxy-Authorization: Basic $auth_b64" $progress $redirect $certificate -o "$2" "$url") + result=$(curl $agent -w '%{http_code}' --connect-timeout 3 --proxy-header "Proxy-Authorization: Basic $auth_b64" $progress $redirect $certificate -o "$1" "$url") else - result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$2" "$url") + result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$1" "$url") fi [ "$result" = "200" ] && return 0 #成功则退出否则重试 export all_proxy="" - result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$2" "$3") + result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$1" "$2") [ "$result" = "200" ] return $? elif ckcmd wget;then - [ "$4" = "echooff" ] && progress='-q' - wget -Y on $progress -O "$2" "$url" && return 0 #成功则退出否则重试 - wget -Y off $progress -O "$2" "$3" + [ "$3" = "echooff" ] && progress='-q' + wget -Y on $progress -O "$1" "$url" && return 0 #成功则退出否则重试 + wget -Y off $progress -O "$1" "$2" return $? else echo "找不到可用下载工具!!!请安装Curl或Wget!!!" diff --git a/scripts/libs/web_restore.sh b/scripts/libs/web_restore.sh new file mode 100644 index 00000000..e0368803 --- /dev/null +++ b/scripts/libs/web_restore.sh @@ -0,0 +1,20 @@ + +# +put_save() { #推送面板选择 + [ -z "$3" ] && request_type=PUT || request_type=$3 + if curl --version >/dev/null 2>&1; then + curl -sS -X "$request_type" -H "Authorization: Bearer $secret" -H "Content-Type:application/json" "$1" -d "$2" >/dev/null + elif wget --version >/dev/null 2>&1; then + wget -q --method="$request_type" --header="Authorization: Bearer $secret" --header="Content-Type:application/json" --body-data="$2" "$1" >/dev/null + fi +} +web_restore() { #还原面板选择 + num=$(cat "$CRASHDIR"/configs/web_save | wc -l) + i=1 + while [ "$i" -le "$num" ]; do + group_name=$(awk -F ',' 'NR=="'${i}'" {print $1}' "$CRASHDIR"/configs/web_save | sed 's/ /%20/g') + now_name=$(awk -F ',' 'NR=="'${i}'" {print $2}' "$CRASHDIR"/configs/web_save) + put_save "http://127.0.0.1:${db_port}/proxies/${group_name}" "{\"name\":\"${now_name}\"}" + i=$((i + 1)) + done +} diff --git a/scripts/libs/web_save.sh b/scripts/libs/web_save.sh new file mode 100644 index 00000000..b9f75c88 --- /dev/null +++ b/scripts/libs/web_save.sh @@ -0,0 +1,30 @@ + +# +get_save() { #获取面板信息 + if curl --version >/dev/null 2>&1; then + curl -s -H "Authorization: Bearer ${secret}" -H "Content-Type:application/json" "$1" + elif [ -n "$(wget --help 2>&1 | grep '\-\-method')" ]; then + wget -q --header="Authorization: Bearer ${secret}" --header="Content-Type:application/json" -O - "$1" + fi +} +web_save() { #最小化保存面板节点选择 + #使用get_save获取面板节点设置 + get_save "http://127.0.0.1:${db_port}/proxies" | sed 's/{}//g' | sed 's/:{/\ +/g'| grep -aE '"Selector"' >"$TMPDIR"/web_proxies + [ -s "$TMPDIR"/web_proxies ] && while read line; do + def=$(echo $line | grep -oE '"all".*",' | awk -F "[\"]" '{print $4}') + now=$(echo $line | grep -oE '"now".*",' | awk -F "[\"]" '{print $4}') + [ "$def" != "$now" ] && { + name=$(echo $line | grep -oE '"name".*",' | awk -F "[\"]" '{print $4}') + echo "${name},${now}" >>"$TMPDIR"/web_save + } + done <"$TMPDIR"/web_proxies + rm -rf "$TMPDIR"/web_proxies + #对比文件,如果有变动且不为空则写入磁盘,否则清除缓存 + for file in web_save web_configs; do + if [ -s "$TMPDIR"/${file} ]; then + . "$CRASHDIR"/libs/compare.sh && compare "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} + [ "$?" = 0 ] && rm -rf "$TMPDIR"/${file} || mv -f "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} + fi + done +} diff --git a/scripts/menu.sh b/scripts/menu.sh index 586cfb66..14d96e80 100644 --- a/scripts/menu.sh +++ b/scripts/menu.sh @@ -7,14 +7,14 @@ CRASHDIR=$( ) CFG_PATH="$CRASHDIR"/configs/ShellCrash.cfg #加载执行目录,失败则初始化 -. "$CRASHDIR"/configs/command.env 2>/dev/null +. "$CRASHDIR"/libs/get_config.sh [ -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命令兼容 #通用工具 . "$CRASHDIR"/libs/set_config.sh . "$CRASHDIR"/libs/check_cmd.sh +. "$CRASHDIR"/menus/1_start.sh errornum() { echo "-----------------------------------------------" echo -e "\033[31m请输入正确的字母或数字!\033[0m" @@ -51,12 +51,6 @@ ckstatus() { #脚本启动前检查 fi versionsh=$(cat "$CRASHDIR"/version) [ -n "$versionsh" ] && versionsh_l=$versionsh - #服务器缺省地址 - [ -z "$mix_port" ] && mix_port=7890 - [ -z "$redir_port" ] && redir_port=7892 - [ -z "$fwmark" ] && fwmark=$redir_port - [ -z "$db_port" ] && db_port=9999 - [ -z "$dns_port" ] && dns_port=1053 [ -z "$redir_mod" ] && redir_mod=纯净模式 #获取本机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}') @@ -132,29 +126,22 @@ ckstatus() { #脚本启动前检查 #检查执行权限 [ ! -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 + for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do echo -e "发现可用的内核文件: \033[36m/tmp/$file\033[0m " read -p "是否加载(会停止当前服务)?(1/0) > " res [ "$res" = 1 ] && { - "$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"/menus/9_upgrade.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 && - switch_core - sleep 1 + zip_type=$(echo "$file" | grep -oE 'tar.gz$|upx$|gz$') + . "$CRASHDIR"/menus/9_upgrade.sh && setcoretype + . "$CRASHDIR"/libs/core_tools.sh && core_check "/tmp/$file" + if [ "$?" = 0 ]; then + echo -e "\033[32m内核加载完成!\033[0m " + switch_core else echo -e "\033[33m检测到不可用的内核文件!可能是文件受损或CPU架构不匹配!\033[0m" - rm -rf /tmp/$file - echo -e "\033[33m内核文件已移除,请认真检查后重新上传!\033[0m" - sleep 2 + rm -rf /tmp/"$file" + echo -e "\033[33m内核文件已移除,请认真检查后重新上传!\033[0m" fi + sleep 1 } echo "-----------------------------------------------" done @@ -205,7 +192,7 @@ main_menu() { exit ;; 1) - . "$CRASHDIR"/menus/1_start.sh && start_service + start_service exit ;; 2) @@ -279,7 +266,7 @@ case "$1" in "$CRASHDIR"/start.sh $2 $3 $4 $5 $6 ;; -i) - . "$CRASHDIR"/init.sh + . "$CRASHDIR"/init.sh 2>/dev/null ;; -st) shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash diff --git a/scripts/menus/1_start.sh b/scripts/menus/1_start.sh index a2230883..e3ec181c 100644 --- a/scripts/menus/1_start.sh +++ b/scripts/menus/1_start.sh @@ -28,16 +28,7 @@ start_core() { elif [ -s $core_config -o -n "$Url" -o -n "$Https" ]; then "$CRASHDIR"/start.sh start #设置循环检测以判定服务启动是否成功 - i=1 - while [ -z "$test" -a "$i" -lt 30 ]; do - sleep 1 - if curl --version >/dev/null 2>&1; then - test=$(curl -s -H "Authorization: Bearer $secret" http://127.0.0.1:${db_port}/configs | grep -o port) - else - test=$(wget -q --header="Authorization: Bearer $secret" -O - http://127.0.0.1:${db_port}/configs | grep -o port) - fi - i=$((i + 1)) - done + . "$CRASHDIR"/libs/start_wait.sh [ -n "$test" -o -n "$(pidof CrashCore)" ] && startover else echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m" diff --git a/scripts/menus/2_settings.sh b/scripts/menus/2_settings.sh index 3ca9ba94..9bff6bf5 100644 --- a/scripts/menus/2_settings.sh +++ b/scripts/menus/2_settings.sh @@ -5,6 +5,7 @@ settings() { #功能设置 #获取设置默认显示 [ -z "$skip_cert" ] && skip_cert=已开启 [ -z "$sniffer" ] && sniffer=未启用 + [ -z "$dns_mod" ] && dns_mod='redir_host' # echo "-----------------------------------------------" echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" @@ -38,7 +39,7 @@ settings() { #功能设置 settings ;; 2) - set_dns_mod + . "$CRASHDIR"/menus/dns.sh && set_dns_mod sleep 1 settings ;; @@ -278,69 +279,6 @@ set_redir_mod() { #代理模式设置 ;; 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=未开启 @@ -830,7 +768,7 @@ set_adv_config() { #端口设置 set_firewall_area() { #代理范围设置 [ -z "$vm_redir" ] && vm_redir='未开启' echo "-----------------------------------------------" - echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6!" + echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用!" echo -e "\033[33m如你使用了第三方DNS如smartdns等,请勿启用本机代理或使用shellcrash用户执行!\033[0m" echo "-----------------------------------------------" echo -e " 1 \033[32m仅代理局域网流量\033[0m" diff --git a/scripts/menus/5_task.sh b/scripts/menus/5_task.sh index 28f3f270..2986ae25 100644 --- a/scripts/menus/5_task.sh +++ b/scripts/menus/5_task.sh @@ -1,196 +1,10 @@ #!/bin/ash # Copyright (C) Juewuy -#加载全局变量 -[ -z "$CRASHDIR" ] && CRASHDIR=$(cd "$(dirname "$(dirname "$0")")"; pwd) -[ -z "$BINDIR" ] && BINDIR=${CRASHDIR} -CFG_PATH=${CRASHDIR}/configs/ShellCrash.cfg -TMPDIR=/tmp/ShellCrash && [ ! -f ${TMPDIR} ] && mkdir -p ${TMPDIR} -. $CFG_PATH >/dev/null 2>&1 -[ -n "$(tar --help 2>&1|grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容 - -setconfig(){ - #参数1代表变量名,参数2代表变量值,参数3即文件路径 - [ -z "$3" ] && configpath=$CFG_PATH || configpath=$3 - [ -n "$(grep "\b${1}=" $configpath)" ] && sed -i "s#\b${1}=.*#${1}=${2}#g" $configpath || echo "${1}=${2}" >> $configpath -} -ckcmd(){ #检查命令是否存在 - command -v sh >/dev/null 2>&1 && command -v $1 >/dev/null 2>&1 || type $1 >/dev/null 2>&1 -} - -#任务命令 -check_update(){ #检查更新工具 - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/crashversion "$1" echooff - [ "$?" = "0" ] && . ${TMPDIR}/crashversion 2>/dev/null - rm -rf ${TMPDIR}/crashversion -} -update_core(){ #自动更新内核 - #检查版本 - check_update bin/version - crash_v_new=$(eval echo \$${crashcore}_v) - if [ -z "$crash_v_new" -o "$crash_v_new" = "$core_v" ];then - logger "任务【自动更新内核】中止-未检测到版本更新" - exit 1 - else - echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash - 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} - fi - else - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/core_new.tar.gz bin/${crashcore}/${core_new}-linux-${cpucore}.tar.gz - fi - if [ "$?" != "0" ];then - logger "任务【自动更新内核】出错-下载失败!" - ${TMPDIR}/CrashCore.tar.gz - return 1 - else - [ -n "$(pidof CrashCore)" ] && ${CRASHDIR}/start.sh stop #停止内核服务防止内存不足 - [ -f ${TMPDIR}/core_new.tar.gz ] && { - mkdir -p ${TMPDIR}/core_new_dir - [ "$BINDIR" = "$TMPDIR" ] && rm -rf ${TMPDIR}/CrashCore #小闪存模式防止空间不足 - tar -zxf "${TMPDIR}/core_new.tar.gz" ${tar_para} -C ${TMPDIR}/core_new_dir/ - for file in $(find ${TMPDIR}/core_new_dir 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_new_dir - } - [ -f ${TMPDIR}/core_new.gz ] && gunzip ${TMPDIR}/core_new.gz >/dev/null && 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 - logger "任务【自动更新内核】出错-内核校验失败!" - rm -rf ${TMPDIR}/core_new.tar.gz - rm -rf ${TMPDIR}/core_new - ${CRASHDIR}/start.sh start - return 1 - else - 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 - logger "任务【自动更新内核】下载完成,正在重启服务!" - setconfig core_v $core_v - ${CRASHDIR}/start.sh start - return 0 - fi - fi - fi -} -update_scripts(){ #自动更新脚本 - #检查版本 - check_update version - if [ -z "$versionsh" -o "$versionsh" = "versionsh_l" ];then - logger "任务【自动更新脚本】中止-未检测到版本更新" - exit 1 - else - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/clashfm.tar.gz "bin/update.tar.gz" - if [ "$?" != "0" ];then - rm -rf ${TMPDIR}/clashfm.tar.gz - logger "任务【自动更新内核】出错-下载失败!" - return 1 - else - #停止服务 - ${CRASHDIR}/start.sh stop - #解压 - tar -zxf "${TMPDIR}/clashfm.tar.gz" ${tar_para} -C ${CRASHDIR}/ - if [ $? -ne 0 ];then - rm -rf ${TMPDIR}/clashfm.tar.gz - logger "任务【自动更新内核】出错-解压失败!" - ${CRASHDIR}/start.sh start - return 1 - else - . ${CRASHDIR}/init.sh >/dev/null - ${CRASHDIR}/start.sh start - return 0 - fi - fi - fi -} -update_mmdb(){ #自动更新数据库 - getgeo(){ - #检查版本 - check_update bin/version - geo_v="$(echo $2 | awk -F "." '{print $1}')_v" #获取版本号类型比如Country_v - geo_v_new=$GeoIP_v - geo_v_now=$(eval echo \$$geo_v) - if [ -z "$geo_v_new" -o "$geo_v_new" = "$geo_v_now" ];then - logger "任务【自动更新数据库文件】跳过-未检测到$2版本更新" - else - #更新文件 - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/$1 "bin/geodata/$2" - if [ "$?" != "0" ];then - logger "任务【自动更新数据库文件】更新【$2】下载失败!" - rm -rf ${TMPDIR}/$1 - else - mv -f ${TMPDIR}/$1 ${BINDIR}/$1 - setconfig $geo_v $GeoIP_v - logger "任务【自动更新数据库文件】更新【$2】成功!" - fi - fi - } - [ -n "${cn_mini_v}" -a -s $CRASHDIR/Country.mmdb ] && getgeo Country.mmdb cn_mini.mmdb - [ -n "${china_ip_list_v}" -a -s $CRASHDIR/cn_ip.txt ] && getgeo cn_ip.txt china_ip_list.txt - [ -n "${china_ipv6_list_v}" -a -s $CRASHDIR/cn_ipv6.txt ] && getgeo cn_ipv6.txt china_ipv6_list.txt - [ -n "${geosite_v}" -a -s $CRASHDIR/GeoSite.dat ] && getgeo GeoSite.dat geosite.dat - [ -n "${geoip_cn_v}" -a -s $CRASHDIR/geoip.db ] && getgeo geoip.db geoip_cn.db - [ -n "${geosite_cn_v}" -a -s $CRASHDIR/geosite.db ] && getgeo geosite.db geosite_cn.db - [ -n "${mrs_geosite_cn_v}" -a -s $CRASHDIR/geosite-cn.mrs ] && getgeo geosite-cn.mrs mrs_geosite_cn.mrs - [ -n "${srs_geoip_cn_v}" -a -s $CRASHDIR/geoip-cn.srs ] && getgeo geoip-cn.srs srs_geoip_cn.srs - [ -n "${srs_geosite_cn_v}" -a -s $CRASHDIR/geosite-cn.srs ] && getgeo geosite-cn.srs srs_geosite_cn.srs - return 0 -} -reset_firewall(){ #重设透明路由防火墙 - ${CRASHDIR}/start.sh stop_firewall - ${CRASHDIR}/start.sh afstart -} -ntp(){ - [ "$crashcore" != singbox ] && ckcmd ntpd && ntpd -n -q -p 203.107.6.88 >/dev/null 2>&1 || exit 0 & -} +#通用工具 +. "$CRASHDIR"/libs/set_config.sh +. "$CRASHDIR"/libs/set_cron.sh #任务工具 -logger(){ - [ "$task_push" = 1 ] && push= || push=off - [ -n "$2" -a "$2" != 0 ] && echo -e "\033[$2m$1\033[0m" - [ "$3" = 'off' ] && push=off - echo "$1" |grep -qE '(每隔|时每)([1-9]|[1-9][0-9])分钟' && push=off - ${CRASHDIR}/start.sh logger "$1" 0 "$push" -} -croncmd(){ - if [ -n "$(crontab -h 2>&1 | grep '\-l')" ];then - crontab $1 - else - crondir="$(crond -h 2>&1 | grep -oE 'Default:.*' | awk -F ":" '{print $2}')" - [ ! -w "$crondir" ] && crondir="/etc/storage/cron/crontabs" - [ ! -w "$crondir" ] && crondir="/var/spool/cron/crontabs" - [ ! -w "$crondir" ] && crondir="/var/spool/cron" - if [ -w "$crondir" ];then - [ "$1" = "-l" ] && cat $crondir/$USER 2>/dev/null - [ -f "$1" ] && cat $1 > $crondir/$USER - else - echo "你的设备不支持定时任务配置,脚本大量功能无法启用,请尝试使用搜索引擎查找安装方式!" - fi - fi -} -cronset(){ - # 参数1代表要移除的关键字,参数2代表要添加的任务语句 - tmpcron=${TMPDIR}/cron_$USER - croncmd -l > $tmpcron 2>/dev/null - sed -i "/$1/d" $tmpcron - sed -i '/^$/d' $tmpcron - echo "$2" >> $tmpcron - croncmd $tmpcron - #华硕/Padavan固件存档在本地,其他则删除 - [ -d /jffs -o -d /etc/storage/clash -o -d /etc/storage/ShellCrash ] && mv -f $tmpcron ${CRASHDIR}/task/cron || rm -f $tmpcron -} set_cron(){ [ -z $week ] && week=* [ -z $hour ] && hour=* @@ -208,7 +22,7 @@ set_cron(){ } set_service(){ # 参数1代表要任务类型,参数2代表任务ID,参数3代表任务描述,参数4代表running任务cron时间 - task_file=${CRASHDIR}/task/$1 + task_file="$CRASHDIR"/task/$1 [ -s $task_file ] && sed -i "/$3/d" $task_file #运行时每分钟执行的任务特殊处理 if [ "$1" = "running" ];then @@ -232,12 +46,12 @@ task_user_add(){ #自定义命令添加 task_command=$script echo -e "请检查输入:\033[32m$task_command\033[0m" #获取本任务ID - task_max_id=$(awk -F '#' '{print $1}' ${CRASHDIR}/task/task.user 2>/dev/null | sort -n | tail -n 1) + task_max_id=$(awk -F '#' '{print $1}' "$CRASHDIR"/task/task.user 2>/dev/null | sort -n | tail -n 1) [ -z "$task_max_id" ] && task_max_id=200 task_id=$((task_max_id + 1)) read -p "请输入任务备注 > " txt [ -n "$txt" ] && task_name=$txt || task_name=自定义任务$task_id - echo "$task_id#$task_command#$task_name" >> ${CRASHDIR}/task/task.user + echo "$task_id#$task_command#$task_name" >> "$CRASHDIR"/task/task.user echo -e "\033[32m自定义任务已添加!\033[0m" sleep 1 else @@ -250,13 +64,13 @@ task_user_del(){ #自定义命令删除 echo -e "请输入对应ID移除对应自定义任务(不会影响内置任务)" echo -e "也可以手动编辑\033[32m${CRASHDIR}/task/task.user\033[0m" echo "-----------------------------------------------" - cat ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^#' | awk -F '#' '{print $1" "$3}' + cat "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^#' | awk -F '#' '{print $1" "$3}' echo "-----------------------------------------------" echo 0 返回上级菜单 echo "-----------------------------------------------" read -p "请输入对应数字 > " num if [ -n "$num" ];then - sed -i "/^$num#/d" ${CRASHDIR}/task/task.user 2>/dev/null + sed -i "/^$num#/d" "$CRASHDIR"/task/task.user 2>/dev/null [ "$num" != 0 ] && task_user_del else echo -e "\033[31m输入错误,请重新输入!\033[0m" @@ -268,7 +82,7 @@ task_add(){ #任务添加 echo -e "\033[36m请选择需要添加的任务\033[0m" echo "-----------------------------------------------" #输出任务列表 - cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | awk -F '#' '{print " "NR" "$3}' + cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | awk -F '#' '{print " "NR" "$3}' echo "-----------------------------------------------" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num @@ -276,9 +90,9 @@ task_add(){ #任务添加 0) ;; [1-9]|[1-9][0-9]) - if [ "$num" -le "$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | wc -l)" ];then - task_id=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $1}') - task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $3}') + if [ "$num" -le "$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | wc -l)" ];then + task_id=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $1}') + task_name=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $3}') task_type else errornum @@ -291,14 +105,14 @@ task_add(){ #任务添加 } task_del(){ #任务删除 #删除定时任务 - croncmd -l > ${TMPDIR}/cron && sed -i "/$1/d" ${TMPDIR}/cron && croncmd ${TMPDIR}/cron - rm -f ${TMPDIR}/cron + croncmd -l > "$TMPDIR"/cron && sed -i "/$1/d" "$TMPDIR"/cron && croncmd "$TMPDIR"/cron + rm -f "$TMPDIR"/cron #删除条件任务 - sed -i "/$1/d" ${CRASHDIR}/task/cron 2>/dev/null - sed -i "/$1/d" ${CRASHDIR}/task/bfstart 2>/dev/null - sed -i "/$1/d" ${CRASHDIR}/task/afstart 2>/dev/null - sed -i "/$1/d" ${CRASHDIR}/task/running 2>/dev/null - sed -i "/$1/d" ${CRASHDIR}/task/affirewall 2>/dev/null + sed -i "/$1/d" "$CRASHDIR"/task/cron 2>/dev/null + sed -i "/$1/d" "$CRASHDIR"/task/bfstart 2>/dev/null + sed -i "/$1/d" "$CRASHDIR"/task/afstart 2>/dev/null + sed -i "/$1/d" "$CRASHDIR"/task/running 2>/dev/null + sed -i "/$1/d" "$CRASHDIR"/task/affirewall 2>/dev/null } task_type(){ #任务条件选择菜单 echo "-----------------------------------------------" @@ -393,20 +207,20 @@ task_type(){ #任务条件选择菜单 task_manager(){ #任务管理列表 echo "-----------------------------------------------" #抽取并生成临时列表 - croncmd -l > ${TMPDIR}/task_cronlist - cat ${TMPDIR}/task_cronlist ${CRASHDIR}/task/running 2>/dev/null | sort -u | grep -oE "task/task.sh .*" | awk -F ' ' '{print $2" "$3}' > ${TMPDIR}/task_list - cat ${CRASHDIR}/task/bfstart ${CRASHDIR}/task/afstart ${CRASHDIR}/task/affirewall 2>/dev/null | awk -F ' ' '{print $2" "$3}' >> ${TMPDIR}/task_list - cat ${TMPDIR}/task_cronlist 2>/dev/null | sort -u | grep -oE " #.*" | grep -v "守护" | awk -F '#' '{print "0 旧版任务-"$2}' >> ${TMPDIR}/task_list - sed -i '/^ *$/d' ${TMPDIR}/task_list - rm -rf ${TMPDIR}/task_cronlist + croncmd -l > "$TMPDIR"/task_cronlist + cat "$TMPDIR"/task_cronlist "$CRASHDIR"/task/running 2>/dev/null | sort -u | grep -oE "task/task.sh .*" | awk -F ' ' '{print $2" "$3}' > "$TMPDIR"/task_list + cat "$CRASHDIR"/task/bfstart "$CRASHDIR"/task/afstart "$CRASHDIR"/task/affirewall 2>/dev/null | awk -F ' ' '{print $2" "$3}' >> "$TMPDIR"/task_list + cat "$TMPDIR"/task_cronlist 2>/dev/null | sort -u | grep -oE " #.*" | grep -v "守护" | awk -F '#' '{print "0 旧版任务-"$2}' >> "$TMPDIR"/task_list + sed -i '/^ *$/d' "$TMPDIR"/task_list + rm -rf "$TMPDIR"/task_cronlist #判断为空则返回 - if [ ! -s ${TMPDIR}/task_list ];then + if [ ! -s "$TMPDIR"/task_list ];then echo -e "\033[31m当前没有可供管理的任务!\033[36m" sleep 1 else echo -e "\033[33m已添加的任务:\033[0m" echo "-----------------------------------------------" - cat ${TMPDIR}/task_list | awk '{print " " NR " " $2}' + cat "$TMPDIR"/task_list | awk '{print " " NR " " $2}' echo "-----------------------------------------------" echo -e " a 清空旧版任务" echo -e " d 清空任务列表" @@ -427,7 +241,7 @@ task_manager(){ #任务管理列表 ;; [1-9]|[1-9][0-9]) - task_txt=$(sed -n "$num p" ${TMPDIR}/task_list) + task_txt=$(sed -n "$num p" "$TMPDIR"/task_list) task_id=$(echo $task_txt | awk '{print $1}') if [ "$task_id" = 0 ];then read -p "旧版任务不支持管理,是否移除?(1/0) > " res @@ -439,7 +253,7 @@ task_manager(){ #任务管理列表 } else task_des=$(echo $task_txt | awk '{print $2}') - task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $3}') + task_name=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $3}') echo "-----------------------------------------------" echo -e "当前任务为:\033[36m $task_des\033[0m" echo -e " 1 \033[33m修改\033[0m当前任务" @@ -459,15 +273,15 @@ task_manager(){ #任务管理列表 task_del $task_des ;; 3) - task_command=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $2}') + task_command=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $2}') eval $task_command && task_res='执行成功!' || task_res='执行失败!' - logger "任务【$task_des】$task_res" 33 off + echo -e "\033[33m任务【$task_des】$task_res\033[0m" sleep 1 ;; 4) echo "-----------------------------------------------" - if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep "$task_name")" ];then - cat ${TMPDIR}/ShellCrash.log | grep "$task_name" + if [ -n "$(cat "$TMPDIR"/ShellCrash.log | grep "$task_name")" ];then + cat "$TMPDIR"/ShellCrash.log | grep "$task_name" else echo -e "\033[31m未找到相关执行记录!\033[0m" fi @@ -504,7 +318,7 @@ task_recom(){ #任务推荐 } task_menu(){ #任务菜单 #检测并创建自定义任务文件 - [ -f ${CRASHDIR}/task/task.user ] || echo '#任务ID(必须>200并顺序排列)#任务命令#任务说明(#号隔开,任务命令和说明中都不允许包含#号)' > ${CRASHDIR}/task/task.user + [ -f "$CRASHDIR"/task/task.user ] || echo '#任务ID(必须>200并顺序排列)#任务命令#任务说明(#号隔开,任务命令和说明中都不允许包含#号)' > "$CRASHDIR"/task/task.user echo "-----------------------------------------------" echo -e "\033[30;47m欢迎使用自动任务功能:\033[0m" echo "-----------------------------------------------" @@ -527,13 +341,13 @@ task_menu(){ #任务菜单 ;; 2) task_manager - rm -rf ${TMPDIR}/task_list + rm -rf "$TMPDIR"/task_list task_menu ;; 3) - if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep '任务【')" ];then + if [ -n "$(cat "$TMPDIR"/ShellCrash.log | grep '任务【')" ];then echo "-----------------------------------------------" - cat ${TMPDIR}/ShellCrash.log | grep '任务【' + cat "$TMPDIR"/ShellCrash.log | grep '任务【' else echo -e "\033[31m未找到任务相关执行日志!\033[0m" fi @@ -543,7 +357,7 @@ task_menu(){ #任务菜单 4) echo "-----------------------------------------------" echo -e "\033[36m请在日志工具中配置相关推送通道及推送开关\033[0m" - log_pusher + . "$CRASHDIR"/menus/8_tools.sh && log_pusher task_menu ;; 5) @@ -563,21 +377,4 @@ task_menu(){ #任务菜单 ;; esac - } - -case "$1" in - menu) - task_menu - ;; - [1-9][0-9][0-9]) - task_command=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$1" | awk -F '#' '{print $2}') - task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$1" | awk -F '#' '{print $3}') - #logger "任务$task_name 开始执行" - eval $task_command && task_res=成功 || task_res=失败 - logger "任务【$2】执行$task_res" - ;; - *) - $1 - ;; -esac diff --git a/scripts/menus/6_core_config.sh b/scripts/menus/6_core_config.sh index a4bf4e2a..19fe3b93 100644 --- a/scripts/menus/6_core_config.sh +++ b/scripts/menus/6_core_config.sh @@ -412,7 +412,7 @@ EOF 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 + . "$CRASHDIR"/libs/core_webget.sh && core_find && ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml if [ "$?" = 0 ];then echo -e "\033[32m配置文件生成成功!\033[0m" mkdir -p ${CRASHDIR}/yamls @@ -514,7 +514,7 @@ EOF 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 + . "$CRASHDIR"/libs/core_webget.sh && core_find && ${TMPDIR}/CrashCore merge ${TMPDIR}/config.json -C ${TMPDIR}/providers if [ "$?" = 0 ];then echo -e "\033[32m配置文件生成成功!如果启动超时建议更新里手动安装Singbox-srs数据库常用包!\033[0m" mkdir -p ${CRASHDIR}/jsons @@ -895,8 +895,8 @@ gen_link_ele(){ #在线生成节点筛选 fi setconfig include "'$include'" } -get_core_config(){ #调用工具下载 - ${CRASHDIR}/start.sh get_core_config +jump_core_config(){ #调用工具下载 + . "$CRASHDIR"/starts/core_config.sh && get_core_config if [ "$?" = 0 ];then if [ "$inuserguide" != 1 ];then read -p "是否启动服务以使配置文件生效?(1/0) > " res @@ -949,7 +949,7 @@ gen_core_config_link(){ #在线生成工具 setconfig Https setconfig Url "'$Url_link'" #获取在线yaml文件 - get_core_config + jump_core_config else echo "-----------------------------------------------" echo -e "\033[31m请先输入订阅或分享链接!\033[0m" @@ -1004,7 +1004,7 @@ set_core_config_link(){ #直接导入配置 setconfig Https "'$link'" setconfig Url #获取在线yaml文件 - get_core_config + jump_core_config else set_core_config_link fi @@ -1117,7 +1117,7 @@ set_core_config(){ #配置文件功能 echo "-----------------------------------------------" read -p "确认更新配置文件?[1/0] > " res if [ "$res" = '1' ]; then - get_core_config + jump_core_config else set_core_config fi diff --git a/scripts/menus/8_tools.sh b/scripts/menus/8_tools.sh index a52faa95..a10939df 100644 --- a/scripts/menus/8_tools.sh +++ b/scripts/menus/8_tools.sh @@ -276,7 +276,7 @@ log_pusher() { 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" ] && { + [ -z "$chat_ID" ] && [ "$TOKEN" != 'publictoken' ] && { 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 @@ -695,8 +695,8 @@ debug(){ 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 + . "$CRASHDIR"/libs/core_webget.sh && core_find && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && echo -e "\033[32m合并成功!\033[0m" + [ "$TMPDIR" = "$BINDIR" ] && rm -rf "$TMPDIR"/CrashCore main_menu ;; *) diff --git a/scripts/menus/9_upgrade.sh b/scripts/menus/9_upgrade.sh index c33071a7..6bd5c392 100644 --- a/scripts/menus/9_upgrade.sh +++ b/scripts/menus/9_upgrade.sh @@ -2,6 +2,8 @@ # Copyright (C) Juewuy . "$CRASHDIR"/libs/check_dir_avail.sh +. "$CRASHDIR"/libs/check_cpucore.sh +. "$CRASHDIR"/libs/web_get_bin.sh error_down(){ echo -e "\033[33m请尝试切换至其他安装源后重新下载!\033[0m" @@ -103,10 +105,10 @@ upgrade(){ } #检查更新 checkupdate(){ - "$CRASHDIR"/start.sh get_bin "$TMPDIR"/version_new version echooff + 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 + get_bin "$TMPDIR"/version_new bin/version echooff } if [ "$?" = "0" ];then . "$TMPDIR"/version_new 2>/dev/null @@ -119,7 +121,7 @@ checkupdate(){ } #更新脚本 getscripts(){ - "$CRASHDIR"/start.sh get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz + get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz if [ "$?" != "0" ];then echo -e "\033[33m文件下载失败!\033[0m" error_down @@ -159,19 +161,6 @@ setscripts(){ 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 "-----------------------------------------------" @@ -234,85 +223,41 @@ switch_core(){ #clash与singbox内核切换 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(){ #下载内核文件 + . "$CRASHDIR"/libs/core_tools.sh #调用下载工具 [ -z "$crashcore" ] && crashcore=meta - [ -z "$cpucore" ] && getcpucore + [ -z "$cpucore" ] && check_cpucore + [ "$crashcore" = unknow ] && setcoretype 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 + core_webget + case "$?" in + 0) + echo -e "\033[32m$crashcore核心下载成功!\033[0m" + sleep 1 + switch_core + ;; + 1) 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 + ;; + *) + echo -e "\033[31m核心文件下载成功但校验失败!请尝试手动指定CPU版本\033[0m" + rm -rf ${TMPDIR}/core_new + rm -rf ${TMPDIR}/core_new.tar.gz + setcpucore + ;; + esac } 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} + 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}') @@ -358,7 +303,7 @@ setcustcore(){ #自定义内核 fi rm -rf "$TMPDIR"/core.list } - [ -z "$cpucore" ] && getcpucore + [ -z "$cpucore" ] && check_cpucore echo "-----------------------------------------------" echo -e "\033[36m此处内核通常源自互联网采集,此处致谢各位开发者!\033[0m" echo -e "\033[33m自定义内核未经过完整适配,使用出现问题请自行解决!\033[0m" @@ -426,7 +371,7 @@ setcustcore(){ #自定义内核 a) read -p "请输入自定义内核的链接地址(必须是以.tar.gz或.gz结尾的压缩文件) > " link [ -n "$link" ] && custcorelink="$link" - crashcore=unknow + setcoretype getcore ;; *) @@ -437,12 +382,11 @@ setcustcore(){ #自定义内核 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 + [ -z "$cpucore" ] && check_cpucore 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" @@ -515,7 +459,7 @@ getgeo(){ #下载Geo文件 #生成链接 echo "-----------------------------------------------" echo 正在从服务器获取数据库文件………… - "$CRASHDIR"/start.sh get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype + get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype if [ "$?" = "1" ];then echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" @@ -543,7 +487,7 @@ setcustgeo(){ #下载自定义数据库文件 getcustgeo(){ echo "-----------------------------------------------" echo "正在获取数据库文件…………" - "$CRASHDIR"/start.sh webget "$TMPDIR"/$geoname $custgeolink + webget "$TMPDIR"/$geoname $custgeolink if [ "$?" = "1" ];then echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" @@ -563,7 +507,7 @@ setcustgeo(){ #下载自定义数据库文件 [ "$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} + 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 @@ -755,7 +699,7 @@ getdb(){ dblink="${update_url}/" echo "-----------------------------------------------" echo 正在连接服务器获取安装文件………… - "$CRASHDIR"/start.sh get_bin "$TMPDIR"/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz + get_bin "$TMPDIR"/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz if [ "$?" = "1" ];then echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" @@ -896,7 +840,7 @@ setdb(){ getcrt(){ echo "-----------------------------------------------" echo "正在连接服务器获取安装文件…………" - "$CRASHDIR"/start.sh get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt + get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt if [ "$?" = "1" ];then echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" @@ -907,7 +851,7 @@ getcrt(){ [ -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 + 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 @@ -1040,7 +984,7 @@ setserver(){ 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 + 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}' diff --git a/scripts/menus/dns.sh b/scripts/menus/dns.sh index ae89dc70..c4394bc9 100644 --- a/scripts/menus/dns.sh +++ b/scripts/menus/dns.sh @@ -16,6 +16,7 @@ set_dns_mod() { #DNS模式设置 echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" echo -e " cn域名realip其他dns2proxy分流" fi + echo "-----------------------------------------------" [ "$dns_mod" = "fake-ip" ] || [ "$dns_mod" = "mix" ] && echo -e " 8 管理Fake-ip过滤列表" echo -e " 9 \033[36mDNS进阶设置\033[0m" diff --git a/scripts/menus/set_crashdir.sh b/scripts/menus/set_crashdir.sh new file mode 100644 index 00000000..e6ed36e5 --- /dev/null +++ b/scripts/menus/set_crashdir.sh @@ -0,0 +1,149 @@ +#!/bin/sh +# Copyright (C) Juewuy + +. /tmp/SC_tmp/libs/check_dir_avail.sh + +set_crashdir() { + set_usb_dir() { + echo -e "请选择安装目录" + du -hL /mnt | awk '{print " "NR" "$2" "$1}' + read -p "请输入相应数字 > " num + dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) + if [ -z "$dir" ]; then + echo -e "\033[31m输入错误!请重新设置!\033[0m" + set_usb_dir + fi + } + set_asus_dir() { + echo -e "请选择U盘目录" + du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}' + read -p "请输入相应数字 > " num + dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p) + if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then + echo -e "\033[31m未找到下载大师自启文件:$dir/asusware.arm/etc/init.d/S50downloadmaster,请检查设置!\033[0m" + set_asus_dir + fi + } + set_cust_dir() { + echo "-----------------------------------------------" + echo "可用路径 剩余空间:" + df -h | awk '{print $6,$4}' | sed 1d + echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!" + read -p "请输入自定义路径 > " dir + if [ "$(dir_avail $dir)" = 0 ] || [ -n "$(echo $dir | grep -E 'tmp|opt|sys')" ]; then + echo "\033[31m路径错误!请重新设置!\033[0m" + set_cust_dir + fi + } + echo "-----------------------------------------------" + if [ -n "$systype" ]; then + [ "$systype" = "Padavan" ] && dir=/etc/storage + [ "$systype" = "mi_snapshot" ] && { + echo -e "\033[33m检测到当前设备为小米官方系统,请选择安装位置\033[0m" + [ -d /data ] && $echo " 1 安装到 /data 目录,剩余空间:$(dir_avail /data -h)(支持软固化功能)" + [ -d /userdisk ] && $echo " 2 安装到 /userdisk 目录,剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)" + [ -d /data/other_vol ] && $echo " 3 安装到 /data/other_vol 目录,剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)" + $echo " 4 安装到自定义目录(不推荐,不明勿用!)" + echo " 0 退出安装" + echo "-----------------------------------------------" + read -p "请输入相应数字 > " num + case "$num" in + 1) + dir=/data + ;; + 2) + dir=/userdisk + ;; + 3) + dir=/data/other_vol + ;; + 4) + set_cust_dir + ;; + *) + exit 1 + ;; + esac + } + [ "$systype" = "asusrouter" ] && { + echo -e "\033[33m检测到当前设备为华硕固件,请选择安装方式\033[0m" + echo -e " 1 基于USB设备安装(限23年9月之前固件,须插入\033[31m任意\033[0mUSB设备)" + echo -e " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)" + echo -e " 3 基于U盘+下载大师安装(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" + echo -e " 0 退出安装" + echo "-----------------------------------------------" + read -p "请输入相应数字 > " num + case "$num" in + 1) + read -p "将脚本安装到USB存储/系统闪存?(1/0) > " res + [ "$res" = "1" ] && set_usb_dir || dir=/jffs + usb_status=1 + ;; + 2) + echo -e "如无法正常开机启动,请重新使用USB方式安装!" + sleep 2 + dir=/jffs + ;; + 3) + echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!" + sleep 2 + set_asus_dir + ;; + *) + exit 1 + ;; + esac + } + [ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt + else + echo -e "\033[33m安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m" + echo -e " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)" + echo -e " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)" + echo -e " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)" + echo -e " 4 在\033[32m外置存储\033[0m中安装" + echo -e " 5 手动设置安装目录" + echo -e " 0 退出安装" + echo "-----------------------------------------------" + read -p "请输入相应数字 > " num + #设置目录 + case "$num" in + 1) + dir=/etc + ;; + 2) + dir=/usr/share + ;; + 3) + dir=~/.local/share + mkdir -p ~/.config/systemd/user + ;; + 4) + set_usb_dir + ;; + 5) + echo "-----------------------------------------------" + echo "可用路径 剩余空间:" + df -h | awk '{print $6,$4}' | sed 1d + echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!" + read -p "请输入自定义路径 > " dir + if [ -z "$dir" ]; then + echo -e "\033[31m路径错误!请重新设置!\033[0m" + setdir + fi + ;; + *) + echo "安装已取消" + exit 1 + ;; + esac + fi + + if [ ! -w $dir ]; then + echo -e "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir + else + echo -e "目标目录\033[32m$dir\033[0m空间剩余:$(dir_avail $dir -h)" + read -p "确认安装?(1/0) > " res + [ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir + fi +} + diff --git a/scripts/start.sh b/scripts/start.sh index 25b2aef2..4501c568 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -6,1294 +6,26 @@ CRASHDIR=$( cd $(dirname $0) pwd ) -#加载执行目录,失败则初始化 -. "$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/get_config.sh #加载工具 . "$CRASHDIR"/libs/set_config.sh +. "$CRASHDIR"/libs/set_cron.sh . "$CRASHDIR"/libs/check_cmd.sh . "$CRASHDIR"/libs/compare.sh . "$CRASHDIR"/libs/logger.sh -. "$CRASHDIR"/starts/fw_start.sh -. "$CRASHDIR"/starts/fw_stop.sh - -#脚本内部工具 -getconfig() { #读取配置及全局变量 - #加载配置文件 - . "$CRASHDIR"/configs/ShellCrash.cfg >/dev/null - #缺省值 - [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' - [ -z "$redir_mod" ] && firewall_area='4' - [ -z "$skip_cert" ] && skip_cert=已开启 - [ -z "$dns_mod" ] && dns_mod=fake-ip - [ -z "$ipv6_redir" ] && ipv6_redir=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$macfilter_type" ] && macfilter_type=黑名单 - [ -z "$mix_port" ] && mix_port=7890 - [ -z "$redir_port" ] && redir_port=7892 - [ -z "$tproxy_port" ] && tproxy_port=7893 - [ -z "$db_port" ] && db_port=9999 - [ -z "$dns_port" ] && dns_port=1053 - [ -z "$fwmark" ] && fwmark=$redir_port - routing_mark=$((fwmark + 2)) - [ -z "$table" ] && table=100 - [ -z "$sniffer" ] && sniffer=已开启 - #是否代理常用端口 - [ -z "$common_ports" ] && common_ports=已开启 - [ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' - [ "$common_ports" = "已开启" ] && ports="-m multiport --dports $multiport" - #内核配置文件 - if echo "$crashcore" | grep -q 'singbox'; then - target=singbox - format=json - core_config="$CRASHDIR"/jsons/config.json - else - target=clash - format=yaml - core_config="$CRASHDIR"/yamls/config.yaml - fi - #检查$iptable命令可用性 - ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables - ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables - #默认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" - #自动生成ua - [ -z "$user_agent" -o "$user_agent" = "auto" ] && { - if echo "$crashcore" | grep -q 'singbox'; then - user_agent="sing-box/singbox/$core_v" - elif [ "$crashcore" = meta ]; then - user_agent="clash.meta/mihomo/$core_v" - else - user_agent="clash" - fi - } - [ "$user_agent" = "none" ] && unset user_agent +. "$CRASHDIR"/libs/web_save.sh +#特殊脚本 +bfstart(){ + . "$CRASHDIR"/starts/bfstart.sh } - -ckgeo() { #查找及下载Geo数据文件 - [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset - find --help 2>&1 | grep -q size && find_para=' -size +20' #find命令兼容 - [ -z "$(find "$BINDIR"/"$1" "$find_para" 2>/dev/null)" ] && { - if [ -n "$(find "$CRASHDIR"/"$1" "$find_para" 2>/dev/null)" ]; then - mv "$CRASHDIR"/"$1" "$BINDIR"/"$1" #小闪存模式移动文件 - else - logger "未找到${1}文件,正在下载!" 33 - get_bin "$BINDIR"/"$1" bin/geodata/"$2" - [ "$?" = "1" ] && rm -rf "${BINDIR}"/"${1}" && logger "${1}文件下载失败,已退出!请前往更新界面尝试手动下载!" 31 && exit 1 - geo_v="$(echo "$2" | awk -F "." '{print $1}')_v" - setconfig "$geo_v" "$(date +"%Y%m%d")" - fi - } +afstart(){ + . "$CRASHDIR"/starts/afstart.sh } - -croncmd() { #定时任务工具 - if [ -n "$(crontab -h 2>&1 | grep '\-l')" ]; then - crontab "$1" - else - crondir="$(crond -h 2>&1 | grep -oE 'Default:.*' | awk -F ":" '{print $2}')" - [ ! -w "$crondir" ] && crondir="/etc/storage/cron/crontabs" - [ ! -w "$crondir" ] && crondir="/var/spool/cron/crontabs" - [ ! -w "$crondir" ] && crondir="/var/spool/cron" - if [ -w "$crondir" ]; then - [ "$1" = "-l" ] && cat "$crondir"/"$USER" 2>/dev/null - [ -f "$1" ] && cat "$1" >"$crondir"/"$USER" - else - echo "你的设备不支持定时任务配置,脚本大量功能无法启用,请尝试使用搜索引擎查找安装方式!" - fi - fi +stop_firewall(){ + . "$CRASHDIR"/starts/fw_stop.sh } -cronset() { #定时任务设置 - # 参数1代表要移除的关键字,参数2代表要添加的任务语句 - tmpcron="$TMPDIR"/cron_tmp - croncmd -l >"$tmpcron" 2>/dev/null - sed -i "/$1/d" "$tmpcron" - sed -i '/^$/d' "$tmpcron" - echo "$2" >>"$tmpcron" - croncmd "$tmpcron" - rm -f "$tmpcron" -} -get_save() { #获取面板信息 - if curl --version >/dev/null 2>&1; then - curl -s -H "Authorization: Bearer ${secret}" -H "Content-Type:application/json" "$1" - elif [ -n "$(wget --help 2>&1 | grep '\-\-method')" ]; then - wget -q --header="Authorization: Bearer ${secret}" --header="Content-Type:application/json" -O - "$1" - fi -} -put_save() { #推送面板选择 - [ -z "$3" ] && request_type=PUT || request_type=$3 - if curl --version >/dev/null 2>&1; then - curl -sS -X "$request_type" -H "Authorization: Bearer $secret" -H "Content-Type:application/json" "$1" -d "$2" >/dev/null - elif wget --version >/dev/null 2>&1; then - wget -q --method="$request_type" --header="Authorization: Bearer $secret" --header="Content-Type:application/json" --body-data="$2" "$1" >/dev/null - fi -} -get_bin() { #专用于项目内部文件的下载 - [ -z "$update_url" ] && update_url=https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@master - if [ -n "$url_id" ]; then - echo "$2" | grep -q '^bin/' && release_type=update #/bin文件改为在update分支下载 - echo "$2" | grep -q '^public/' && release_type=dev #/public文件改为在dev分支下载 - [ -z "$release_type" ] && release_type=master - if [ "$url_id" = 101 -o "$url_id" = 104 ]; then - url="$(grep "$url_id" "$CRASHDIR"/configs/servers.list | awk '{print $3}')@$release_type/$2" #jsdelivr特殊处理 - else - url="$(grep "$url_id" "$CRASHDIR"/configs/servers.list | awk '{print $3}')/$release_type/$2" - fi - else - url="$update_url/$2" - fi - $0 webget "$1" "$url" "$3" "$4" "$5" "$6" -} -mark_time() { #时间戳 - date +%s >"$TMPDIR"/crash_start_time -} -getlanip() { #获取局域网host地址 - i=1 - while [ "$i" -le "20" ]; do - host_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Ev 'utun|iot|peer|docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g') #ipv4局域网网段 - [ "$ipv6_redir" = "已开启" ] && host_ipv6=$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g') #ipv6公网地址段 - [ -f "$TMPDIR"/ShellCrash.log ] && break - [ -n "$host_ipv4" -a "$ipv6_redir" != "已开启" ] && break - [ -n "$host_ipv4" -a -n "$host_ipv6" ] && break - sleep 1 && i=$((i + 1)) - done - #添加自定义ipv4局域网网段 - if [ "$replace_default_host_ipv4" == "已启用" ]; then - host_ipv4="$cust_host_ipv4" - else - host_ipv4="$host_ipv4$cust_host_ipv4" - fi - #缺省配置 - [ -z "$host_ipv4" ] && host_ipv4='192.168.0.0/16 10.0.0.0/12 172.16.0.0/12' - host_ipv6="fe80::/10 fd00::/8 $host_ipv6" - #获取本机出口IP地址 - local_ipv4=$(ip route 2>&1 | grep -Ev 'utun|iot|docker|linkdown' | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u) - [ -z "$local_ipv4" ] && local_ipv4=$(ip route 2>&1 | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u) - #保留地址 - [ -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" - [ -z "$reserve_ipv6" ] && reserve_ipv6="::/128 ::1/128 ::ffff:0:0/96 64:ff9b::/96 100::/64 2001::/32 2001:20::/28 2001:db8::/32 2002::/16 fe80::/10 ff00::/8" -} -parse_singbox_dns() { #singbox的dns分割工具 - first_dns=$(echo "$1" | cut -d',' -f1 | cut -d' ' -f1) - type="" - server="" - port="" - case "$first_dns" in - *://*) - type="${first_dns%%://*}" - tmp="${first_dns#*://}" - ;; - *) - type="udp" - tmp="$first_dns" - ;; - esac - case "$tmp" in - \[*\]*) - server="${tmp%%]*}" - server="${server#[}" - port="${tmp#*\]}" - port="${port#:}" - ;; - *) - server="${tmp%%[:/]*}" - port="${tmp#*:}" - [ "$port" = "$tmp" ] && port="" - ;; - esac - if [ -z "$port" ]; then - case "$type" in - udp|tcp) port=53 ;; - doh|https) port=443 ;; - dot|tls) port=853 ;; - *) port=53 ;; - esac - fi - # 输出 - echo '"type": "'"$type"'", "server": "'"$server"'", "server_port": '"$port"',' -} -urlencode() { - LC_ALL=C - printf '%s' "$1" \ - | hexdump -v -e '/1 "%02X\n"' \ - | while read -r hex; do - case "$hex" in - 2D|2E|5F|7E|3[0-9]|4[1-9A-F]|5[0-9A]|6[1-9A-F]|7[0-9A-E]) - printf "\\$(printf '%03o' "0x$hex")" - ;; - *) - printf "%%%s" "$hex" - ;; - esac - done -} -#配置文件相关 -check_clash_config() { #检查clash配置文件 - #检测节点或providers - sed -n "/^proxies:/,/^[a-z]/ { /^[a-z]/d; p; }" "$core_config_new" >"$TMPDIR"/proxies.yaml - if ! grep -Eq 'server:|server":|server'\'':' "$TMPDIR"/proxies.yaml && ! grep -q 'proxy-providers:' "$core_config_new"; then - echo "-----------------------------------------------" - logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31 - cat "$TMPDIR"/proxies.yaml - sleep 1 - echo "-----------------------------------------------" - echo "请尝试使用6-2或者6-3的方式生成配置文件!" - exit 1 - fi - rm -rf "$TMPDIR"/proxies.yaml - #检测旧格式 - if cat "$core_config_new" | grep 'Proxy Group:' >/dev/null; then - echo "-----------------------------------------------" - logger "已经停止对旧格式配置文件的支持!!!" 31 - echo -e "请使用新格式或者使用【在线生成配置文件】功能!" - echo "-----------------------------------------------" - exit 1 - fi - #检测不支持的加密协议 - if cat "$core_config_new" | grep 'cipher: chacha20,' >/dev/null; then - echo "-----------------------------------------------" - logger "已停止支持chacha20加密,请更换更安全的节点加密协议!" 31 - echo "-----------------------------------------------" - exit 1 - fi - #检测并去除无效策略组 - [ -n "$url_type" ] && ckcmd xargs && { - cat "$core_config_new" | sed '/^rules:/,$d' | grep -A 15 "\- name:" | xargs | sed 's/- name: /\n/g' | sed 's/ type: .*proxies: /#/g' | sed 's/- //g' | grep -E '#DIRECT $|#DIRECT$' | grep -Ev '全球直连|direct|Direct' | awk -F '#' '{print $1}' >"$TMPDIR"/clash_proxies_$USER - while read line; do - sed -i "/- $line/d" "$core_config_new" - sed -i "/- name: $line/,/- DIRECT/d" "$core_config_new" - done <"$TMPDIR"/clash_proxies_$USER - rm -rf "$TMPDIR"/clash_proxies_$USER - } -} -check_singbox_config() { #检查singbox配置文件 - #检测节点或providers - if ! grep -qE '"(socks|http|shadowsocks(r)?|vmess|trojan|wireguard|hysteria(2)?|vless|shadowtls|tuic|ssh|tor|providers|anytls|soduku)"' "$core_config_new"; then - echo "-----------------------------------------------" - logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31 - echo "请尝试使用6-2或者6-3的方式生成配置文件!" - exit 1 - fi - #删除不兼容的旧版内容 - [ "$(wc -l <"$core_config_new")" -lt 3 ] && { - sed -i 's/^.*"inbounds":/{"inbounds":/' "$core_config_new" - sed -i 's/{[^{}]*"dns-out"[^{}]*}//g' "$core_config_new" - } - #检查不支持的旧版内容 - grep -q '"sni"' "$core_config_new" && { - logger "获取到了不支持的旧版(<1.12)配置文件【$core_config_new】!" 31 - echo "请尝试使用支持1.12以上版本内核的方式生成配置文件!" - exit 1 - } - #检测并去除无效策略组 - [ -n "$url_type" ] && { - #获得无效策略组名称 - grep -oE '\{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]' "$core_config_new" | sed -n 's/.*"tag":"\([^"]*\)".*/\1/p' >"$TMPDIR"/singbox_tags - #删除策略组 - sed -i 's/{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]}//g; s/{"type":"[^"]*","tag":"[^"]*","outbounds":\["DIRECT"\],"url":"[^"]*","interval":"[^"]*","tolerance":[^}]*}//g' "$core_config_new" - #删除全部包含策略组名称的规则 - while read line; do - sed -i "s/\"$line\"//g" "$core_config_new" - done <"$TMPDIR"/singbox_tags - rm -rf "$TMPDIR"/singbox_tags - } - #清理多余逗号 - sed -i 's/,\+/,/g; s/\[,/\[/g; s/,]/]/g' "$core_config_new" -} -update_servers() { #更新servers.list - get_bin "$TMPDIR"/servers.list public/servers.list - [ "$?" = 0 ] && mv -f "$TMPDIR"/servers.list "$CRASHDIR"/configs/servers.list -} -get_core_config() { #下载内核配置文件 - [ -z "$rule_link" ] && rule_link=1 - [ -z "$server_link" ] || [ $server_link -gt $(grep -aE '^4' "$CRASHDIR"/configs/servers.list | wc -l) ] && server_link=1 - Server=$(grep -aE '^3|^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}') - Server_ua=$(grep -aE '^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $4}') - Config=$(grep -aE '^5' "$CRASHDIR"/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $3}') - #如果传来的是Url链接则合成Https链接,否则直接使用Https链接 - if [ -z "$Https" ]; then - #Urlencord转码处理保留字符 - if ckcmd hexdump;then - Url=$(echo $Url | sed 's/%26/\&/g') #处理分隔符 - urlencodeUrl="exclude=$(urlencode "$exclude")&include=$(urlencode "$include")&url=$(urlencode "$Url")&config=$(urlencode "$Config")" - else - urlencodeUrl="exclude=$exclude&include=$include&url=$Url&config=$Config" - fi - Https="${Server}/sub?target=${target}&${Server_ua}=${user_agent}&insert=true&new_name=true&scv=true&udp=true&${urlencodeUrl}" - url_type=true - fi - #输出 - echo "-----------------------------------------------" - logger 正在连接服务器获取【${target}】配置文件………… - echo -e "链接地址为:\033[4;32m$Https\033[0m" - echo 可以手动复制该链接到浏览器打开并查看数据是否正常! - #获取在线config文件 - core_config_new="$TMPDIR"/${target}_config.${format} - rm -rf ${core_config_new} - $0 webget "$core_config_new" "$Https" echoon rediron skipceron "$user_agent" - if [ "$?" != "0" ]; then - if [ -z "$url_type" ]; then - echo "-----------------------------------------------" - logger "配置文件获取失败!" 31 - echo -e "\033[31m请尝试使用【在线生成配置文件】功能!\033[0m" - echo "-----------------------------------------------" - exit 1 - else - if [ -n "$retry" ] && [ "$retry" -ge 3 ]; then - logger "无法获取配置文件,请检查链接格式以及网络连接状态!" 31 - echo -e "\033[32m也可用浏览器下载以上链接后,使用WinSCP手动上传到/tmp目录后执行crash命令本地导入!\033[0m" - exit 1 - else - retry=$((retry + 1)) - logger "配置文件获取失败!" 31 - if [ "$retry" = 1 ]; then - echo -e "\033[32m尝试更新服务器列表并使用其他服务器获取配置!\033[0m" - update_servers - else - echo -e "\033[32m尝试使用其他服务器获取配置!\033[0m" - fi - echo -e "正在重试\033[33m第$retry次/共3次!\033[0m" - if [ "$server_link" -ge 4 ]; then - server_link=0 - fi - server_link=$((server_link + 1)) - setconfig server_link $server_link - Https="" - get_core_config - fi - fi - else - Https="" - if echo "$crashcore" | grep -q 'singbox'; then - check_singbox_config - else - check_clash_config - fi - #如果不同则备份并替换文件 - if [ -s $core_config ]; then - compare $core_config_new $core_config - [ "$?" = 0 ] || mv -f $core_config $core_config.bak && mv -f $core_config_new $core_config - else - mv -f $core_config_new $core_config - fi - echo -e "\033[32m已成功获取配置文件!\033[0m" - fi - return 0 -} -modify_yaml() { #修饰clash配置文件 - ##########需要变更的配置########### - [ -z "$skip_cert" ] && skip_cert=已开启 - [ "$ipv6_dns" = "已开启" ] && dns_v6='true' || dns_v6='false' - external="external-controller: 0.0.0.0:$db_port" - if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ]; then - [ "$crashcore" = 'meta' ] && tun_meta=', device: utun, auto-route: false, auto-detect-interface: false' - tun="tun: {enable: true, stack: system$tun_meta}" - else - tun='tun: {enable: false}' - fi - exper='experimental: {ignore-resolve-fail: true, interface-name: en0}' - #Meta内核专属配置 - [ "$crashcore" = 'meta' ] && { - [ "$redir_mod" != "纯净模式" ] && [ -z "$(grep 'PROCESS' "$CRASHDIR"/yamls/*.yaml)" ] && find_process='find-process-mode: "off"' - } - #dns配置 - [ -z "$(cat "$CRASHDIR"/yamls/user.yaml 2>/dev/null | grep '^dns:')" ] && { - [ "$crashcore" != meta ] && dns_resolver='223.5.5.5' - cat >"$TMPDIR"/dns.yaml </dev/null | grep -v '#' | sed "s/^/ - '/" | sed "s/$/'/" >>"$TMPDIR"/dns.yaml - else - echo " - '+.*'" >>"$TMPDIR"/dns.yaml #使用fake-ip模拟redir_host - fi - #mix模式fakeip绕过cn - [ "$dns_mod" = "mix" ] && echo ' - "rule-set:cn"' >>"$TMPDIR"/dns.yaml - #mix模式和route模式插入分流设置 - if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then - [ "$dns_protect" != "OFF" ] && dns_final="$dns_fallback" || dns_final="$dns_nameserver" - cat >>"$TMPDIR"/dns.yaml <>"$TMPDIR"/dns.yaml <"$TMPDIR"/set.yaml </dev/null)" ]; then - #NTP劫持 - cat >"$TMPDIR"/hosts.yaml <>"$TMPDIR"/hosts.yaml - else - #加载本机hosts - sys_hosts=/etc/hosts - [ -f /data/etc/custom_hosts ] && sys_hosts=/data/etc/custom_hosts - while read line; do - [ -n "$(echo "$line" | grep -oE "([0-9]{1,3}[\.]){3}")" ] && - [ -z "$(echo "$line" | grep -oE '^#')" ] && - hosts_ip=$(echo $line | awk '{print $1}') && - hosts_domain=$(echo $line | awk '{print $2}') && - [ -z "$(cat "$TMPDIR"/hosts.yaml | grep -oE "$hosts_domain")" ] && - echo " '$hosts_domain': $hosts_ip" >>"$TMPDIR"/hosts.yaml - done <$sys_hosts - fi - fi - #分割配置文件 - yaml_char='proxies proxy-groups proxy-providers rules rule-providers sub-rules listeners' - for char in $yaml_char; do - sed -n "/^$char:/,/^[a-z]/ { /^[a-z]/d; p; }" $core_config >"$TMPDIR"/${char}.yaml - done - #跳过本地tls证书验证 - [ "$skip_cert" = "已开启" ] && sed -i 's/skip-cert-verify: false/skip-cert-verify: true/' "$TMPDIR"/proxies.yaml || - sed -i 's/skip-cert-verify: true/skip-cert-verify: false/' "$TMPDIR"/proxies.yaml - #插入自定义策略组 - sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml - sed -i "/#自定义策略组/d" "$TMPDIR"/proxy-groups.yaml - [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxy-groups.yaml 2>/dev/null)" ] && { - #获取空格数 - space_name=$(grep -aE '^ *- \{?name: ' "$TMPDIR"/proxy-groups.yaml | head -n 1 | grep -oE '^ *') - space_proxy="$space_name " - #合并自定义策略组到proxy-groups.yaml - cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml - cat "$TMPDIR"/proxy-groups.yaml >>"$TMPDIR"/proxy-groups_add.yaml - mv -f "$TMPDIR"/proxy-groups_add.yaml "$TMPDIR"/proxy-groups.yaml - oldIFS="$IFS" - grep "\- name: " "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | while read line; do #将自定义策略组插入现有的proxy-group - new_group=$(echo $line | grep -Eo '^ *- name:.*#' | cut -d'#' -f1 | sed 's/.*name: //g') - proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") - IFS="#" - for name in $proxy_groups; do - line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 - [ -n "$line_a" ] && { - line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 - line_c=$((line_a + line_b - 1)) #计算需要插入的行号 - space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 - [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${new_group} #自定义策略组" "$TMPDIR"/proxy-groups.yaml - } - done - IFS="$oldIFS" - done - } - #插入自定义代理 - sed -i "/#自定义代理/d" "$TMPDIR"/proxies.yaml - sed -i "/#自定义代理/d" "$TMPDIR"/proxy-groups.yaml - [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxies.yaml 2>/dev/null)" ] && { - space_proxy=$(cat "$TMPDIR"/proxies.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') #获取空格数 - cat "$CRASHDIR"/yamls/proxies.yaml | sed "s/^ *- /${space_proxy}- /g" | sed "/^#/d" | sed "/^ *$/d" | sed 's/#.*/ #自定义代理/g' >>"$TMPDIR"/proxies.yaml #插入节点 - oldIFS="$IFS" - cat "$CRASHDIR"/yamls/proxies.yaml | sed "/^#/d" | while read line; do #将节点插入proxy-group - proxy_name=$(echo $line | grep -Eo 'name: .+, ' | cut -d',' -f1 | sed 's/name: //g') - proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") - IFS="#" - for name in $proxy_groups; do - line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 - [ -n "$line_a" ] && { - line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 - line_c=$((line_a + line_b - 1)) #计算需要插入的行号 - space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 - [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${proxy_name} #自定义代理" "$TMPDIR"/proxy-groups.yaml - } - done - IFS="$oldIFS" - done - } - #添加自定义入站 - [ "$vms_service" = ON ] || [ "$sss_service" = ON ] && { - . "$CRASHDIR"/configs/gateway.cfg - . "$CRASHDIR"/libs/meta_listeners.sh - } - #节点绕过功能支持 - sed -i "/#节点绕过/d" "$TMPDIR"/rules.yaml - [ "$proxies_bypass" = "已启用" ] && { - cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '!a[$0]++' | sed 's/^/\ -\ IP-CIDR,/g' | sed 's|$|/32,DIRECT,no-resolve #节点绕过|g' >>"$TMPDIR"/proxies_bypass - cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -vE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?' | awk '!a[$0]++' | sed 's/^/\ -\ DOMAIN,/g' | sed 's/$/,DIRECT #节点绕过/g' >>"$TMPDIR"/proxies_bypass - cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/proxies_bypass - mv -f "$TMPDIR"/proxies_bypass "$TMPDIR"/rules.yaml - } - #插入自定义规则 - sed -i "/#自定义规则/d" "$TMPDIR"/rules.yaml - [ -s "$CRASHDIR"/yamls/rules.yaml ] && { - cat "$CRASHDIR"/yamls/rules.yaml | sed "/^#/d" | sed '$a\' | sed 's/$/ #自定义规则/g' >"$TMPDIR"/rules.add - cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/rules.add - mv -f "$TMPDIR"/rules.add "$TMPDIR"/rules.yaml - } - #mix和route模式生成rule-providers - [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && ! grep -q 'cn:' "$TMPDIR"/rule-providers.yaml && ! grep -q '^rule-providers' "$CRASHDIR"/yamls/others.yaml 2>/dev/null && { - space=$(sed -n "1p" "$TMPDIR"/rule-providers.yaml | grep -oE '^ *') #获取空格数 - [ -z "$space" ] && space=' ' - echo "${space}cn: {type: http, behavior: domain, format: mrs, path: ./ruleset/cn.mrs, url: https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@update/bin/geodata/mrs_geosite_cn.mrs}" >>"$TMPDIR"/rule-providers.yaml - } - #对齐rules中的空格 - sed -i 's/^ *-/ -/g' "$TMPDIR"/rules.yaml - #合并文件 - [ -s "$CRASHDIR"/yamls/user.yaml ] && { - yaml_user="$CRASHDIR"/yamls/user.yaml - #set和user去重,且优先使用user.yaml - cp -f "$TMPDIR"/set.yaml "$TMPDIR"/set_bak.yaml - for char in mode allow-lan log-level tun experimental external-ui-url interface-name dns store-selected; do - [ -n "$(grep -E "^$char" $yaml_user)" ] && sed -i "/^$char/d" "$TMPDIR"/set.yaml - done - } - [ -s "$TMPDIR"/dns.yaml ] && yaml_dns="$TMPDIR"/dns.yaml - [ -s "$TMPDIR"/hosts.yaml ] && yaml_hosts="$TMPDIR"/hosts.yaml - [ -s "$CRASHDIR"/yamls/others.yaml ] && yaml_others="$CRASHDIR"/yamls/others.yaml - yaml_add= - for char in $yaml_char; do #将额外配置文件合并 - [ -s "$TMPDIR"/${char}.yaml ] && { - sed -i "1i\\${char}:" "$TMPDIR"/${char}.yaml - yaml_add="$yaml_add $TMPDIR/${char}.yaml" - } - done - #合并完整配置文件 - cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_hosts $yaml_user $yaml_others $yaml_add >"$TMPDIR"/config.yaml - #测试自定义配置文件 - "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml >/dev/null - if [ "$?" != 0 ]; then - logger "$("$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml | grep -Eo 'error.*=.*')" 31 - logger "自定义配置文件校验失败!将使用基础配置文件启动!" 33 - logger "错误详情请参考 "$TMPDIR"/error.yaml 文件!" 33 - mv -f "$TMPDIR"/config.yaml "$TMPDIR"/error.yaml >/dev/null 2>&1 - sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml - mv -f "$TMPDIR"/set_bak.yaml "$TMPDIR"/set.yaml >/dev/null 2>&1 - #合并基础配置文件 - cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_add >"$TMPDIR"/config.yaml - sed -i "/#自定义/d" "$TMPDIR"/config.yaml - fi - #建立软连接 - [ ""$TMPDIR"" = ""$BINDIR"" ] || ln -sf "$TMPDIR"/config.yaml "$BINDIR"/config.yaml 2>/dev/null || cp -f "$TMPDIR"/config.yaml "$BINDIR"/config.yaml - #清理缓存 - for char in $yaml_char set set_bak dns hosts; do - rm -f "$TMPDIR"/${char}.yaml - done -} -modify_json() { #修饰singbox1.13配置文件 - #提取配置文件以获得outbounds.json,providers.json及route.json - "$TMPDIR"/CrashCore format -c $core_config >"$TMPDIR"/format.json - echo '{' >"$TMPDIR"/jsons/outbounds.json - echo '{' >"$TMPDIR"/jsons/route.json - cat "$TMPDIR"/format.json | sed -n '/"outbounds":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/outbounds.json - [ "$crashcore" = "singboxr" ] && { - echo '{' >"$TMPDIR"/jsons/providers.json - cat "$TMPDIR"/format.json | sed -n '/^ "providers":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/providers.json - } - cat "$TMPDIR"/format.json | sed -n '/"route":/,/^\( "[a-z]\|}\)/p' | sed '$d' >>"$TMPDIR"/jsons/route.json - #生成endpoints.json - [ "$ts_service" = ON ] || [ "$wg_service" = ON ] && { - . "$CRASHDIR"/configs/gateway.cfg - . "$CRASHDIR"/libs/sb_endpoints.sh - } - #生成log.json - cat >"$TMPDIR"/jsons/log.json <"$TMPDIR"/jsons/add_hosts.json </dev/null | grep -Ev '#|\*|\+|Mijia' | sed '/^\s*$/d' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') - fake_ip_filter_suffix=$(cat ${CRASHDIR}/configs/fake_ip_filter ${CRASHDIR}/configs/fake_ip_filter.list 2>/dev/null | grep -v '.\*' | grep -E '\*|\+' | sed 's/^[*+]\.//' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') - fake_ip_filter_regex=$(cat ${CRASHDIR}/configs/fake_ip_filter ${CRASHDIR}/configs/fake_ip_filter.list 2>/dev/null | grep '.\*' | sed 's/\./\\\\./g' | sed 's/\*/.\*/' | sed 's/^+/.\+/' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') - [ -n "$fake_ip_filter_domain" ] && fake_ip_filter_domain="{ \"domain\": [$fake_ip_filter_domain], \"server\": \"dns_direct\" }," - [ -n "$fake_ip_filter_suffix" ] && fake_ip_filter_suffix="{ \"domain_suffix\": [$fake_ip_filter_suffix], \"server\": \"dns_direct\" }," - [ -n "$fake_ip_filter_regex" ] && fake_ip_filter_regex="{ \"domain_regex\": [$fake_ip_filter_regex], \"server\": \"dns_direct\" }," - proxy_dns='{ "query_type": ["A", "AAAA"], "server": "dns_fakeip", "strategy": "'"$strategy"'", "rewrite_ttl": 1 }' - #mix模式插入fakeip过滤规则 - [ "$dns_mod" = "mix" ] && direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" },' - } - [ "$dns_mod" = "route" ] && { - global_dns=dns_proxy - direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" }' - } - #防泄露设置 - [ "$dns_protect" = "OFF" ] && sed -i 's/"server": "dns_proxy"/"server": "dns_direct"/g' "$TMPDIR"/jsons/route.json - #生成add_rule_set.json - [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && - [ -z "$(cat "$CRASHDIR"/jsons/*.json | grep -Ei '"tag" *: *"cn"')" ] && - cat >"$TMPDIR"/jsons/add_rule_set.json <"$TMPDIR"/jsons/dns.json <"$TMPDIR"/jsons/add_route.json <"$TMPDIR"/jsons/certificate.json <"$TMPDIR"/jsons/inbounds.json <>"$TMPDIR"/jsons/tun.json <"$TMPDIR"/jsons/add_outbounds.json <"$TMPDIR"/jsons/experimental.json </dev/null)" ] && { - cat "$CRASHDIR"/yamls/rules.yaml | - sed '/#.*/d' | - sed 's/,no-resolve//g' | - grep -oE '\-.*,.*,.*' | - sed 's/- DOMAIN-SUFFIX,/{ "domain_suffix": [ "/g' | - sed 's/- DOMAIN-KEYWORD,/{ "domain_keyword": [ "/g' | - sed 's/- IP-CIDR,/{ "ip_cidr": [ "/g' | - sed 's/- SRC-IP-CIDR,/{ "._ip_cidr": [ "/g' | - sed 's/- DST-PORT,/{ "port": [ "/g' | - sed 's/- SRC-PORT,/{ "._port": [ "/g' | - sed 's/- GEOIP,/{ "geoip": [ "/g' | - sed 's/- GEOSITE,/{ "geosite": [ "/g' | - sed 's/- IP-CIDR6,/{ "ip_cidr": [ "/g' | - sed 's/- DOMAIN,/{ "domain": [ "/g' | - sed 's/- PROCESS-NAME,/{ "process_name": [ "/g' | - sed 's/,/" ], "outbound": "/g' | - sed 's/$/" },/g' | - sed '1i\{ "route": { "rules": [ ' | - sed '$s/,$/ ] } }/' >"$TMPDIR"/jsons/cust_add_rules.json - [ ! -s "$TMPDIR"/jsons/cust_add_rules.json ] && rm -rf "$TMPDIR"/jsons/cust_add_rules.json - } - #清理route.json中的process_name规则以及"auto_detect_interface" - sed -i '/"process_name": \[/,/],$/d' "$TMPDIR"/jsons/route.json - sed -i '/"process_name": "[^"]*",/d' "$TMPDIR"/jsons/route.json - sed -i 's/"auto_detect_interface": true/"auto_detect_interface": false/g' "$TMPDIR"/jsons/route.json - #跳过本地tls证书验证 - if [ -z "$skip_cert" -o "$skip_cert" = "已开启" ]; then - sed -i 's/"insecure": false/"insecure": true/' "$TMPDIR"/jsons/outbounds.json "$TMPDIR"/jsons/providers.json 2>/dev/null - else - sed -i 's/"insecure": true/"insecure": false/' "$TMPDIR"/jsons/outbounds.json "$TMPDIR"/jsons/providers.json 2>/dev/null - fi - #判断可用并修饰outbounds&providers&route.json结尾 - for file in outbounds providers route; do - if [ -n "$(grep ${file} "$TMPDIR"/jsons/${file}.json 2>/dev/null)" ]; then - sed -i 's/^ },$/ }/; s/^ ],$/ ]/' "$TMPDIR"/jsons/${file}.json - echo '}' >>"$TMPDIR"/jsons/${file}.json - else - rm -rf "$TMPDIR"/jsons/${file}.json - fi - done - #加载自定义配置文件 - mkdir -p "$TMPDIR"/jsons_base - #以下为覆盖脚本的自定义文件 - for char in log dns ntp certificate experimental; do - [ -s "$CRASHDIR"/jsons/${char}.json ] && { - ln -sf "$CRASHDIR"/jsons/${char}.json "$TMPDIR"/jsons/cust_${char}.json - mv -f "$TMPDIR"/jsons/${char}.json "$TMPDIR"/jsons_base #如果重复则临时备份 - } - done - #以下为增量添加的自定义文件 - for char in others endpoints inbounds outbounds providers route services; do - [ -s "$CRASHDIR"/jsons/${char}.json ] && { - ln -sf "$CRASHDIR"/jsons/${char}.json "$TMPDIR"/jsons/cust_${char}.json - } - done - #测试自定义配置文件 - if ! error=$("$TMPDIR"/CrashCore check -D "$BINDIR" -C "$TMPDIR"/jsons 2>&1); then - echo $error - error_file=$(echo $error | grep -Eo 'cust.*\.json' | sed 's/cust_//g') - [ "$error_file" = 'add_rules.json' ] && error_file="$CRASHDIR"/yamls/rules.yaml自定义规则 || error_file="$CRASHDIR"/jsons/$error_file - logger "自定义配置文件校验失败,请检查【${error_file}】文件!" 31 - logger "尝试使用基础配置文件启动~" 33 - #清理自定义配置文件并还原基础配置 - rm -rf "$TMPDIR"/jsons/cust_* - mv -f "$TMPDIR"/jsons_base/* "$TMPDIR"/jsons 2>/dev/null - fi - #清理缓存 - rm -rf "$TMPDIR"/*.json - rm -rf "$TMPDIR"/jsons_base - return 0 -} - -#设置路由规则 -cn_ip_route() { #CN-IP绕过 - ckgeo cn_ip.txt china_ip_list.txt - [ -f "$BINDIR"/cn_ip.txt ] && [ "$firewall_mod" = iptables ] && { - # see https://raw.githubusercontent.com/Hackl0us/GeoIP2-CN/release/CN-ip-cidr.txt - echo "create cn_ip hash:net family inet hashsize 10240 maxelem 10240" >"$TMPDIR"/cn_ip.ipset - awk '!/^$/&&!/^#/{printf("add cn_ip %s'" "'\n",$0)}' "$BINDIR"/cn_ip.txt >>"$TMPDIR"/cn_ip.ipset - ipset destroy cn_ip >/dev/null 2>&1 - ipset -! restore <"$TMPDIR"/cn_ip.ipset - rm -rf "$TMPDIR"/cn_ip.ipset - } -} -cn_ipv6_route() { #CN-IPV6绕过 - ckgeo cn_ipv6.txt china_ipv6_list.txt - [ -f "$BINDIR"/cn_ipv6.txt ] && [ "$firewall_mod" = iptables ] && { - #ipv6 - #see https://ispip.clang.cn/all_cn_ipv6.txt - echo "create cn_ip6 hash:net family inet6 hashsize 5120 maxelem 5120" >"$TMPDIR"/cn_ipv6.ipset - awk '!/^$/&&!/^#/{printf("add cn_ip6 %s'" "'\n",$0)}' "$BINDIR"/cn_ipv6.txt >>"$TMPDIR"/cn_ipv6.ipset - ipset destroy cn_ip6 >/dev/null 2>&1 - ipset -! restore <"$TMPDIR"/cn_ipv6.ipset - rm -rf "$TMPDIR"/cn_ipv6.ipset - } -} -#启动相关 -web_save() { #最小化保存面板节点选择 - #使用get_save获取面板节点设置 - 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"' | grep -aoE '"name":.*"now":".*",' >"$TMPDIR"/web_proxies - [ -s "$TMPDIR"/web_proxies ] && while read line; do - def=$(echo $line | grep -oE '"all".*",' | awk -F "[\"]" '{print $4}') - now=$(echo $line | grep -oE '"now".*",' | awk -F "[\"]" '{print $4}') - [ "$def" != "$now" ] && { - name=$(echo $line | grep -oE '"name".*",' | awk -F "[\"]" '{print $4}') - echo "${name},${now}" >>"$TMPDIR"/web_save - } - done <"$TMPDIR"/web_proxies - rm -rf "$TMPDIR"/web_proxies - #获取面板设置 - #[ "$crashcore" != singbox ] && get_save http://127.0.0.1:${db_port}/configs > "$TMPDIR"/web_configs - #对比文件,如果有变动且不为空则写入磁盘,否则清除缓存 - for file in web_save web_configs; do - if [ -s "$TMPDIR"/${file} ]; then - compare "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} - [ "$?" = 0 ] && rm -rf "$TMPDIR"/${file} || mv -f "$TMPDIR"/${file} "$CRASHDIR"/configs/${file} - fi - done -} -web_restore() { #还原面板选择 - #设置循环检测面板端口以判定服务启动是否成功 - test="" - i=1 - while [ -z "$test" -a "$i" -lt 30 ]; do - test=$(get_save http://127.0.0.1:${db_port}/proxies | grep -o proxies) - i=$((i + 1)) - sleep 2 - done - [ -n "$test" ] && { - #发送节点选择数据 - [ -s "$CRASHDIR"/configs/web_save ] && { - num=$(cat "$CRASHDIR"/configs/web_save | wc -l) - i=1 - while [ "$i" -le "$num" ]; do - group_name=$(awk -F ',' 'NR=="'${i}'" {print $1}' "$CRASHDIR"/configs/web_save | sed 's/ /%20/g') - now_name=$(awk -F ',' 'NR=="'${i}'" {print $2}' "$CRASHDIR"/configs/web_save) - put_save http://127.0.0.1:${db_port}/proxies/${group_name} "{\"name\":\"${now_name}\"}" - i=$((i + 1)) - done - } - #还原面板设置 - #[ "$crashcore" != singbox ] && [ -s "$CRASHDIR"/configs/web_configs ] && { - #sleep 5 - #put_save http://127.0.0.1:${db_port}/configs "$(cat "$CRASHDIR"/configs/web_configs)" PATCH - #} - } -} -makehtml() { #生成面板跳转文件 - cat >"$BINDIR"/ui/index.html < - - - - - - - - ShellCrash面板提示 - - -
-

您还未安装本地面板

-

请在脚本更新功能中(9-4)安装
或者使用在线面板:

-

请复制当前地址/ui(不包括)前面的内容,填入url位置即可连接

- Zashboard面板(推荐)
-
如已安装,请使用Ctrl+F5强制刷新此页面!
-
- -&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - [ -z "$host_pac" ] && host_pac=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/\/[0-9][0-9].*$//g' | head -n 1) - cat >"$TMPDIR"/shellcrash_pac <&1 | grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容 - [ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容 - tar_core() { - mkdir -p "$TMPDIR"/core_tmp - tar -zxf "$1" ${tar_para} -C "$TMPDIR"/core_tmp/ - for file in $(find "$TMPDIR"/core_tmp $find_para 2>/dev/null); do - [ -f $file ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|pre)')" ] && mv -f $file "$TMPDIR"/"$2" - done - rm -rf "$TMPDIR"/core_tmp - } - [ -z "$(find "$TMPDIR"/CrashCore $find_para 2>/dev/null)" ] && [ -n "$(find "$BINDIR"/CrashCore $find_para 2>/dev/null)" ] && mv "$BINDIR"/CrashCore "$TMPDIR"/CrashCore - [ -z "$(find "$TMPDIR"/CrashCore $find_para 2>/dev/null)" ] && [ -n "$(find "$BINDIR"/CrashCore.tar.gz $find_para 2>/dev/null)" ] && - tar_core "$BINDIR"/CrashCore.tar.gz CrashCore - [ -z "$(find "$TMPDIR"/CrashCore $find_para 2>/dev/null)" ] && { - logger "未找到【$crashcore】核心,正在下载!" 33 - [ -z "$cpucore" ] && . "$CRASHDIR"/webget.sh && getcpucore - [ -z "$cpucore" ] && logger 找不到设备的CPU信息,请手动指定处理器架构类型! 31 && exit 1 - get_bin "$TMPDIR"/CrashCore.tar.gz "bin/$crashcore/${target}-linux-${cpucore}.tar.gz" - #校验内核 - tar_core "$TMPDIR"/CrashCore.tar.gz core_new - chmod +x "$TMPDIR"/core_new - if echo "$crashcore" | grep -q 'singbox'; then - core_v=$("$TMPDIR"/core_new version 2>/dev/null | grep version | awk '{print $3}') - COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' - else - core_v=$("$TMPDIR"/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') - COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' - fi - if [ -z "$core_v" ]; then - rm -rf "$TMPDIR"/CrashCore - logger "核心下载失败,请重新运行或更换安装源!" 31 - exit 1 - else - mv -f "$TMPDIR"/core_new "$TMPDIR"/CrashCore - mv -f "$TMPDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.tar.gz - setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env && . "$CRASHDIR"/configs/command.env - setconfig crashcore $crashcore - setconfig core_v $core_v - fi - } - [ ! -x "$TMPDIR"/CrashCore ] && chmod +x "$TMPDIR"/CrashCore 2>/dev/null #自动授权 - [ "$start_old" != "已开启" -a "$(cat /proc/1/comm)" = "systemd" ] && restorecon -RF $CRASHDIR 2>/dev/null #修复SELinux权限问题 - return 0 -} -core_exchange() { #升级为高级内核 - #$1:目标内核 $2:提示语句 - logger "检测到${2}!将改为使用${1}核心启动!" 33 - rm -rf "$TMPDIR"/CrashCore - rm -rf "$BINDIR"/CrashCore - rm -rf "$BINDIR"/CrashCore.tar.gz - crashcore="$1" - setconfig crashcore "$1" - echo "-----------------------------------------------" -} -clash_check() { #clash启动前检查 - #检测vless/hysteria协议 - [ "$crashcore" != "meta" ] && [ -n "$(cat $core_config | grep -oE 'type: vless|type: hysteria')" ] && core_exchange meta 'vless/hy协议' - #检测是否存在高级版规则或者tun模式 - if [ "$crashcore" = "clash" ]; then - [ -n "$(cat $core_config | grep -aiE '^script:|proxy-providers|rule-providers|rule-set')" ] || - [ "$redir_mod" = "混合模式" ] || - [ "$redir_mod" = "Tun模式" ] && core_exchange meta '当前内核不支持的配置' - fi - [ "$crashcore" = "clash" ] && [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '0:7890' /etc/passwd)" ] && - core_exchange meta '当前内核不支持非root用户启用本机代理' - core_check - #预下载GeoIP数据库并排除存在自定义数据库链接的情况 - [ -n "$(grep -oEi 'geoip:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geoip:|mmdb:' "$CRASHDIR"/yamls/*.yaml)" ] && ckgeo Country.mmdb cn_mini.mmdb - #预下载GeoSite数据库并排除存在自定义数据库链接的情况 - [ -n "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && ckgeo GeoSite.dat geosite.dat - #预下载cn.mrs数据库 - [ -n "$(cat "$CRASHDIR"/yamls/*.yaml | grep -oEi 'rule_set.*cn')" -o "$dns_mod" = "mix" ] && ckgeo ruleset/cn.mrs mrs_geosite_cn.mrs - return 0 -} -singbox_check() { #singbox启动前检查 - #检测singboxr专属功能 - [ "$crashcore" != "singboxr" ] && [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oE '"shadowsocksr"|"providers"')" ] && core_exchange singboxr 'singboxr内核专属功能' - core_check - #预下载geoip-cn.srs数据库 - [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"geoip-cn"')" ] && ckgeo ruleset/geoip-cn.srs srs_geoip_cn.srs - #预下载cn.srs数据库 - [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"cn"')" -o "$dns_mod" = "mix" ] && ckgeo ruleset/cn.srs srs_geosite_cn.srs - return 0 -} -network_check() { #检查是否联网 - for text in 223.5.5.5 1.2.4.8 dns.alidns.com doh.pub; do - ping -c 3 $text >/dev/null 2>&1 && return 0 - sleep 5 - done - logger "当前设备无法连接网络,已停止启动!" 33 - exit 1 -} -bfstart() { #启动前 - routing_mark=$((fwmark + 2)) - #检测网络连接 - [ "$network_check" != "已禁用" ] && [ ! -f "$TMPDIR"/crash_start_time ] && ckcmd ping && network_check - [ ! -d "$BINDIR"/ui ] && mkdir -p "$BINDIR"/ui - [ -z "$crashcore" ] && crashcore=meta - #执行条件任务 - [ -s "$CRASHDIR"/task/bfstart ] && . "$CRASHDIR"/task/bfstart - #检查内核配置文件 - if [ ! -f $core_config ]; then - if [ -n "$Url" -o -n "$Https" ]; then - logger "未找到配置文件,正在下载!" 33 - get_core_config - else - logger "未找到配置文件链接,请先导入配置文件!" 31 - exit 1 - fi - fi - #检查dashboard文件 - if [ -f "$CRASHDIR"/ui/CNAME -a ! -f "$BINDIR"/ui/CNAME ]; then - cp -rf "$CRASHDIR"/ui "$BINDIR" - fi - [ ! -s "$BINDIR"/ui/index.html ] && makehtml #如没有面板则创建跳转界面 - catpac #生成pac文件 - #内核及内核配置文件检查 - if echo "$crashcore" | grep -q 'singbox'; then - singbox_check - [ -d "$TMPDIR"/jsons ] && rm -rf "$TMPDIR"/jsons/* || mkdir -p "$TMPDIR"/jsons #准备目录 - [ "$disoverride" != "1" ] && modify_json || ln -sf $core_config "$TMPDIR"/jsons/config.json - else - clash_check - [ "$disoverride" != "1" ] && modify_yaml || ln -sf $core_config "$TMPDIR"/config.yaml - fi - #检查下载cnip绕过相关文件 - [ "$firewall_mod" = nftables ] || ckcmd ipset && [ "$dns_mod" != "fake-ip" ] && { - [ "$cn_ip_route" = "已开启" ] && cn_ip_route - [ "$ipv6_redir" = "已开启" ] && [ "$cn_ip_route" = "已开启" ] && cn_ipv6_route - } - #添加shellcrash用户 - [ "$firewall_area" = 2 ] || [ "$firewall_area" = 3 ] || [ "$(cat /proc/1/comm)" = "systemd" ] && - [ -z "$(id shellcrash 2>/dev/null | grep 'root')" ] && { - ckcmd userdel && userdel shellcrash 2>/dev/null - sed -i '/0:7890/d' /etc/passwd - sed -i '/x:7890/d' /etc/group - if ckcmd useradd; then - useradd shellcrash -u 7890 - sed -Ei s/7890:7890/0:7890/g /etc/passwd - else - echo "shellcrash:x:0:7890:::" >>/etc/passwd - fi - } - #清理debug日志 - rm -rf "$TMPDIR"/debug.log - rm -rf "$CRASHDIR"/debug.log - return 0 -} -afstart() { #启动后 - [ -z "$firewall_area" ] && firewall_area=1 - #延迟启动 - [ ! -f "$TMPDIR"/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && { - logger "ShellCrash将延迟$start_delay秒启动" 31 - sleep $start_delay - } - #设置循环检测面板端口以判定服务启动是否成功 - i=1 - while [ -z "$test" -a "$i" -lt 30 ]; do - echo "$i" | grep -q '10' && echo -ne "服务正在启动,请耐心等待!\r" - sleep 1 - if curl --version >/dev/null 2>&1; then - test=$(curl -s -H "Authorization: Bearer $secret" http://127.0.0.1:${db_port}/configs | grep -o port) - else - test=$(wget -q --header="Authorization: Bearer $secret" -O - http://127.0.0.1:${db_port}/configs | grep -o port) - fi - i=$((i + 1)) - done - if [ -n "$test" -o -n "$(pidof CrashCore)" ]; then - [ "$start_old" = "已开启" ] && rm -rf "$TMPDIR"/CrashCore #删除缓存目录内核文件 - start_firewall #配置防火墙流量劫持 - mark_time #标记启动时间 - [ -s "$CRASHDIR"/configs/web_save ] && web_restore >/dev/null 2>&1 & #后台还原面板配置 - { - sleep 5 - logger ShellCrash服务已启动! - } & #推送日志 - ckcmd mtd_storage.sh && mtd_storage.sh save >/dev/null 2>&1 & #Padavan保存/etc/storage - #加载定时任务 - [ -s "$CRASHDIR"/task/cron ] && croncmd "$CRASHDIR"/task/cron - [ -s "$CRASHDIR"/task/running ] && { - cronset '运行时每' - while read line; do - cronset '2fjdi124dd12s' "$line" - done <"$CRASHDIR"/task/running - } - [ "$start_old" = "已开启" ] && cronset '保守模式守护进程' "* * * * * test -z \"\$(pidof CrashCore)\" && "$CRASHDIR"/start.sh daemon #ShellCrash保守模式守护进程" - #加载条件任务 - [ -s "$CRASHDIR"/task/afstart ] && { . "$CRASHDIR"/task/afstart; } & - [ -s "$CRASHDIR"/task/affirewall -a -s /etc/init.d/firewall -a ! -f /etc/init.d/firewall.bak ] && { - #注入防火墙 - line=$(grep -En "fw.* restart" /etc/init.d/firewall | cut -d ":" -f 1) - sed -i.bak "${line}a\\. "$CRASHDIR"/task/affirewall" /etc/init.d/firewall - line=$(grep -En "fw.* start" /etc/init.d/firewall | cut -d ":" -f 1) - sed -i "${line}a\\. "$CRASHDIR"/task/affirewall" /etc/init.d/firewall - } & - #启动TG机器人 - [ "$bot_tg_service" = ON ] && "$CRASHDIR"/menus/bot_tg.sh & - else - start_error - $0 stop - fi -} -start_error() { #启动报错 - if [ "$start_old" != "已开启" ] && ckcmd journalctl; then - journalctl -u shellcrash >$TMPDIR/core_test.log - else - PID=$(pidof CrashCore) && [ -n "$PID" ] && kill -9 $PID >/dev/null 2>&1 - ${COMMAND} >"$TMPDIR"/core_test.log 2>&1 & - sleep 2 - kill $! >/dev/null 2>&1 - fi - error=$(cat $TMPDIR/core_test.log | grep -iEo 'error.*=.*|.*ERROR.*|.*FATAL.*') - logger "服务启动失败!请查看报错信息!详细信息请查看$TMPDIR/core_test.log" 33 - logger "$error" 31 - exit 1 -} -start_old() { #保守模式 +#保守模式启动 +start_old(){ #使用传统后台执行二进制文件的方式执行 if ckcmd su && [ -n "$(grep 'shellcrash:x:0:7890' /etc/passwd)" ]; then su shellcrash -c "$COMMAND >/dev/null 2>&1" & @@ -1303,20 +35,6 @@ start_old() { #保守模式 fi afstart & } -#杂项 -update_config() { #更新订阅并重启 - get_core_config && - $0 restart -} -hotupdate() { #热更新订阅 - get_core_config - core_check - modify_$format && - put_save http://127.0.0.1:${db_port}/configs "{\"path\":\""$CRASHDIR"/config.$format\"}" - rm -rf "$TMPDIR"/CrashCore -} - -getconfig #读取配置及全局变量 case "$1" in @@ -1325,7 +43,7 @@ start) stop_firewall #清理路由策略 #使用不同方式启动服务 if [ "$firewall_area" = "5" ]; then #主旁转发 - start_firewall + . "$CRASHDIR"/starts/fw_start.sh elif [ "$start_old" = "已开启" ]; then bfstart && start_old elif [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then @@ -1335,7 +53,7 @@ start) FragmentPath=$(systemctl show -p FragmentPath shellcrash | sed 's/FragmentPath=//') [ -f $FragmentPath ] && setconfig ExecStart "$COMMAND >/dev/null" "$FragmentPath" systemctl daemon-reload - systemctl start shellcrash.service || start_error + systemctl start shellcrash.service || . "$CRASHDIR"/starts/start_error.sh } elif grep -q 's6' /proc/1/comm; then bfstart && /command/s6-svc -u /run/service/shellcrash && { @@ -1379,6 +97,9 @@ restart) $0 stop $0 start ;; +init) + . "$CRASHDIR"/starts/general_init.sh + ;; daemon) if [ -f $TMPDIR/crash_start_time ]; then $0 start @@ -1405,78 +126,6 @@ debug) fi afstart ;; -init) - if [ -d "/etc/storage/clash" -o -d "/etc/storage/ShellCrash" ]; then - i=1 - while [ ! -w /etc/profile -a "$i" -lt 10 ]; do - sleep 3 && i=$((i + 1)) - done - [ -w /etc/profile ] && profile=/etc/profile || profile=/etc_ro/profile - mount -t tmpfs -o remount,rw,size=45M tmpfs /tmp #增加/tmp空间以适配新的内核压缩方式 - sed -i '' $profile #将软链接转化为一般文件 - elif [ -d "/jffs" ]; then - sleep 60 - if [ -w /etc/profile ]; then - profile=/etc/profile - else - profile=$(cat /etc/profile | grep -oE '\-f.*jffs.*profile' | awk '{print $2}') - fi - fi - [ -z "$my_alias" ] && my_alias=crash - sed -i "/ShellCrash\/menu.sh/"d "$profile" - echo "alias ${my_alias}=\"sh $CRASHDIR/menu.sh\"" >>"$profile" - sed -i "/export CRASHDIR/d" "$profile" - echo "export CRASHDIR=\"$CRASHDIR\"" >>"$profile" - [ -f "$CRASHDIR"/.dis_startup ] && cronset "保守模式守护进程" || $0 start - ;; -webget) - #设置临时代理 - if pidof CrashCore >/dev/null; then - [ -n "$authentication" ] && auth="$authentication@" || auth="" - export all_proxy="http://${auth}127.0.0.1:$mix_port" - url=$(printf '%s\n' "$3" | - sed -e 's#https://.*jsdelivr.net/gh/juewuy/ShellCrash[@|/]#https://raw.githubusercontent.com/juewuy/ShellCrash/#' \ - -e 's#https://gh.jwsc.eu.org/#https://raw.githubusercontent.com/juewuy/ShellCrash/#') - else - url=$(printf '%s\n' "$3" | - sed 's#https://raw.githubusercontent.com/juewuy/ShellCrash/#https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@#') - fi - #参数【$2】代表下载目录,【$3】代表在线地址 - #参数【$4】代表输出显示,【$5】不启用重定向 - #参数【$6】代表验证证书,【$7】使用自定义UA - [ -n "$7" ] && agent="--user-agent \"$7\"" - if wget --help 2>&1 | grep -q 'show-progress' >/dev/null 2>&1; then - [ "$4" = "echooff" ] && progress='-q' || progress='-q --show-progress' - [ "$5" = "rediroff" ] && redirect='--max-redirect=0' || redirect='' - [ "$6" = "skipceroff" ] && certificate='' || certificate='--no-check-certificate' - wget -Y on $agent $progress $redirect $certificate --timeout=3 -O "$2" "$url" && exit 0 #成功则退出否则重试 - wget -Y off $agent $progress $redirect $certificate --timeout=5 -O "$2" "$3" - exit $? - elif curl --version >/dev/null 2>&1; then - [ "$4" = "echooff" ] && progress='-s' || progress='-#' - [ "$5" = "rediroff" ] && redirect='' || redirect='-L' - [ "$6" = "skipceroff" ] && certificate='' || certificate='-k' - if curl --version | grep -q '^curl 8.' && ckcmd base64; then - auth_b64=$(printf '%s' "$authentication" | base64) - result=$(curl $agent -w '%{http_code}' --connect-timeout 3 --proxy-header "Proxy-Authorization: Basic $auth_b64" $progress $redirect $certificate -o "$2" "$url") - else - result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$2" "$url") - fi - [ "$result" = "200" ] && exit 0 #成功则退出否则重试 - export all_proxy="" - result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$2" "$3") - [ "$result" = "200" ] - exit $? - elif ckcmd wget;then - [ "$4" = "echooff" ] && progress='-q' - wget -Y on $progress -O "$2" "$url" && exit 0 #成功则退出否则重试 - wget -Y off $progress -O "$2" "$3" - exit $? - else - echo "找不到可用下载工具!!!请安装Curl或Wget!!!" - exit 1 - fi - ;; *) "$1" "$2" "$3" "$4" "$5" "$6" "$7" ;; diff --git a/scripts/starts/afstart.sh b/scripts/starts/afstart.sh new file mode 100644 index 00000000..410b769a --- /dev/null +++ b/scripts/starts/afstart.sh @@ -0,0 +1,58 @@ +#!/bin/ash +# Copyright (C) Juewuy + +#初始化目录 +[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd) +. "$CRASHDIR"/libs/get_config.sh +#加载工具 +. "$CRASHDIR"/libs/check_cmd.sh +. "$CRASHDIR"/libs/logger.sh +. "$CRASHDIR"/libs/set_cron.sh +#缺省值 +[ -z "$firewall_area" ] && firewall_area=1 +#延迟启动 +[ ! -f "$TMPDIR"/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && { + logger "ShellCrash将延迟$start_delay秒启动" 31 + sleep "$start_delay" +} +#设置循环检测面板端口以判定服务启动是否成功 +. "$CRASHDIR"/libs/start_wait.sh +if [ -n "$test" -o -n "$(pidof CrashCore)" ]; then + [ "$start_old" = "已开启" ] && rm -rf "$TMPDIR"/CrashCore #删除缓存目录内核文件 + . "$CRASHDIR"/starts/fw_start.sh #配置防火墙流量劫持 + date +%s >"$TMPDIR"/crash_start_time #标记启动时间 + #后台还原面板配置 + [ -s "$CRASHDIR"/configs/web_save ] && { + . "$CRASHDIR"/libs/web_restore.sh + web_restore >/dev/null 2>&1 & + } + #推送日志 + { + sleep 5 + logger ShellCrash服务已启动! + } & + ckcmd mtd_storage.sh && mtd_storage.sh save >/dev/null 2>&1 & #Padavan保存/etc/storage + #加载定时任务 + [ -s "$CRASHDIR"/task/cron ] && croncmd "$CRASHDIR"/task/cron + [ -s "$CRASHDIR"/task/running ] && { + cronset '运行时每' + while read line; do + cronset '2fjdi124dd12s' "$line" + done <"$CRASHDIR"/task/running + } + [ "$start_old" = "已开启" ] && cronset '保守模式守护进程' "* * * * * test -z \"\$(pidof CrashCore)\" && $CRASHDIR/start.sh daemon #ShellCrash保守模式守护进程" + #加载条件任务 + [ -s "$CRASHDIR"/task/afstart ] && { . "$CRASHDIR"/task/afstart; } & + [ -s "$CRASHDIR"/task/affirewall -a -s /etc/init.d/firewall -a ! -f /etc/init.d/firewall.bak ] && { + #注入防火墙 + line=$(grep -En "fw.* restart" /etc/init.d/firewall | cut -d ":" -f 1) + sed -i.bak "${line}a\\. "$CRASHDIR"/task/affirewall" /etc/init.d/firewall + line=$(grep -En "fw.* start" /etc/init.d/firewall | cut -d ":" -f 1) + sed -i "${line}a\\. $CRASHDIR/task/affirewall" /etc/init.d/firewall + } & + #启动TG机器人 + [ "$bot_tg_service" = ON ] && "$CRASHDIR"/menus/bot_tg.sh & +else + . "$CRASHDIR"/starts/start_error.sh + "$CRASHDIR"/start.sh stop +fi diff --git a/scripts/starts/bfstart.sh b/scripts/starts/bfstart.sh new file mode 100644 index 00000000..b53b64c3 --- /dev/null +++ b/scripts/starts/bfstart.sh @@ -0,0 +1,136 @@ +#!/bin/ash +# Copyright (C) Juewuy + +[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd) +. "$CRASHDIR"/libs/get_config.sh +[ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1 +[ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR" +#加载工具 +. "$CRASHDIR"/libs/check_cmd.sh +. "$CRASHDIR"/libs/check_target.sh +. "$CRASHDIR"/libs/logger.sh +. "$CRASHDIR"/libs/web_get_bin.sh +. "$CRASHDIR"/libs/compare.sh +. "$CRASHDIR"/starts/check_geo.sh +. "$CRASHDIR"/starts/check_core.sh +#缺省值 +[ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' +[ -z "$dns_mod" ] && dns_mod='redir_host' +[ -z "$redir_mod" ] && firewall_area='4' + +makehtml() { #生成面板跳转文件 + cat >"$BINDIR"/ui/index.html < + + + + + + + + ShellCrash面板提示 + + +
+

您还未安装本地面板

+

请在脚本更新功能中(9-4)安装
或者使用在线面板:

+

请复制当前地址/ui(不包括)前面的内容,填入url位置即可连接

+ Zashboard面板(推荐)
+
如已安装,请使用Ctrl+F5强制刷新此页面!
+
+ +&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + [ -z "$host_pac" ] && host_pac=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/\/[0-9][0-9].*$//g' | head -n 1) + cat >"$TMPDIR"/shellcrash_pac </dev/null | grep 'root')" ] && { + ckcmd userdel && userdel shellcrash 2>/dev/null + sed -i '/0:7890/d' /etc/passwd + sed -i '/x:7890/d' /etc/group + if ckcmd useradd; then + useradd shellcrash -u 7890 + sed -Ei s/7890:7890/0:7890/g /etc/passwd + else + echo "shellcrash:x:0:7890:::" >>/etc/passwd + fi +} +#清理debug日志 +rm -rf /tmp/ShellCrash/debug.log +rm -rf "$CRASHDIR"/debug.log +return 0 + diff --git a/scripts/starts/check_cnip.sh b/scripts/starts/check_cnip.sh new file mode 100644 index 00000000..cda13078 --- /dev/null +++ b/scripts/starts/check_cnip.sh @@ -0,0 +1,24 @@ + +ck_cn_ipv4() { #CN-IP绕过 + check_geo cn_ip.txt china_ip_list.txt + [ -f "$BINDIR"/cn_ip.txt ] && [ "$firewall_mod" = iptables ] && { + # see https://raw.githubusercontent.com/Hackl0us/GeoIP2-CN/release/CN-ip-cidr.txt + echo "create cn_ip hash:net family inet hashsize 10240 maxelem 10240" >"$TMPDIR"/cn_ip.ipset + awk '!/^$/&&!/^#/{printf("add cn_ip %s'" "'\n",$0)}' "$BINDIR"/cn_ip.txt >>"$TMPDIR"/cn_ip.ipset + ipset destroy cn_ip >/dev/null 2>&1 + ipset -! restore <"$TMPDIR"/cn_ip.ipset + rm -rf "$TMPDIR"/cn_ip.ipset + } +} +ck_cn_ipv6() { #CN-IPV6绕过 + check_geo cn_ipv6.txt china_ipv6_list.txt + [ -f "$BINDIR"/cn_ipv6.txt ] && [ "$firewall_mod" = iptables ] && { + #ipv6 + #see https://ispip.clang.cn/all_cn_ipv6.txt + echo "create cn_ip6 hash:net family inet6 hashsize 5120 maxelem 5120" >"$TMPDIR"/cn_ipv6.ipset + awk '!/^$/&&!/^#/{printf("add cn_ip6 %s'" "'\n",$0)}' "$BINDIR"/cn_ipv6.txt >>"$TMPDIR"/cn_ipv6.ipset + ipset destroy cn_ip6 >/dev/null 2>&1 + ipset -! restore <"$TMPDIR"/cn_ipv6.ipset + rm -rf "$TMPDIR"/cn_ipv6.ipset + } +} \ No newline at end of file diff --git a/scripts/starts/check_core.sh b/scripts/starts/check_core.sh new file mode 100644 index 00000000..6e4e3849 --- /dev/null +++ b/scripts/starts/check_core.sh @@ -0,0 +1,18 @@ + +. "$CRASHDIR"/libs/check_target.sh +. "$CRASHDIR"/libs/core_tools.sh +. "$CRASHDIR"/configs/command.env + +check_core() { #检查及下载内核文件 + [ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容 + [ -z "$(find "$TMPDIR"/CrashCore $find_para 2>/dev/null)" ] && core_find + [ -z "$(find "$TMPDIR"/CrashCore 2>/dev/null)" ] && { + logger "未找到【$crashcore】核心,正在下载!" 33 + [ -z "$cpucore" ] && . "$CRASHDIR"/libs/check_cpucore.sh && check_cpucore + [ -z "$cpucore" ] && logger 找不到设备的CPU信息,请手动指定处理器架构类型! 31 && exit 1 + core_webget || logger "核心下载失败,请重新运行或更换安装源!" 31 + } + [ ! -x "$TMPDIR"/CrashCore ] && chmod +x "$TMPDIR"/CrashCore 2>/dev/null #自动授权 + [ "$start_old" != "已开启" -a "$(cat /proc/1/comm)" = "systemd" ] && restorecon -RF "$CRASHDIR" 2>/dev/null #修复SELinux权限问题 + return 0 +} diff --git a/scripts/starts/check_geo.sh b/scripts/starts/check_geo.sh new file mode 100644 index 00000000..d9129198 --- /dev/null +++ b/scripts/starts/check_geo.sh @@ -0,0 +1,16 @@ + +check_geo() { #查找及下载Geo数据文件 + [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset + find --help 2>&1 | grep -q size && find_para=' -size +20' #find命令兼容 + [ -z "$(find "$BINDIR"/"$1" "$find_para" 2>/dev/null)" ] && { + if [ -n "$(find "$CRASHDIR"/"$1" "$find_para" 2>/dev/null)" ]; then + mv "$CRASHDIR"/"$1" "$BINDIR"/"$1" #小闪存模式移动文件 + else + logger "未找到${1}文件,正在下载!" 33 + get_bin "$BINDIR"/"$1" bin/geodata/"$2" + [ "$?" = "1" ] && rm -rf "${BINDIR}"/"${1}" && logger "${1}文件下载失败,已退出!请前往更新界面尝试手动下载!" 31 && exit 1 + geo_v="$(echo "$2" | awk -F "." '{print $1}')_v" + setconfig "$geo_v" "$(date +"%Y%m%d")" + fi + } +} \ No newline at end of file diff --git a/scripts/starts/check_network.sh b/scripts/starts/check_network.sh new file mode 100644 index 00000000..d36fa012 --- /dev/null +++ b/scripts/starts/check_network.sh @@ -0,0 +1,11 @@ +#!/bin/sh +# Copyright (C) Juewuy + +network_check() { #检查是否联网 + for text in 223.5.5.5 1.2.4.8 dns.alidns.com doh.pub; do + ping -c 3 $text >/dev/null 2>&1 && return 0 + sleep 5 + done + logger "当前设备无法连接网络,已停止启动!" 33 + exit 1 +} \ No newline at end of file diff --git a/scripts/starts/clash_check.sh b/scripts/starts/clash_check.sh new file mode 100644 index 00000000..2bccff74 --- /dev/null +++ b/scripts/starts/clash_check.sh @@ -0,0 +1,21 @@ + +clash_check() { #clash启动前检查 + #检测vless/hysteria协议 + [ "$crashcore" != "meta" ] && [ -n "$(cat $core_config | grep -oE 'type: vless|type: hysteria')" ] && core_exchange meta 'vless/hy协议' + #检测是否存在高级版规则或者tun模式 + if [ "$crashcore" = "clash" ]; then + [ -n "$(cat $core_config | grep -aiE '^script:|proxy-providers|rule-providers|rule-set')" ] || + [ "$redir_mod" = "混合模式" ] || + [ "$redir_mod" = "Tun模式" ] && core_exchange meta '当前内核不支持的配置' + fi + [ "$crashcore" = "clash" ] && [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '0:7890' /etc/passwd)" ] && + core_exchange meta '当前内核不支持非root用户启用本机代理' + check_core + #预下载GeoIP数据库并排除存在自定义数据库链接的情况 + [ -n "$(grep -oEi 'geoip:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geoip:|mmdb:' "$CRASHDIR"/yamls/*.yaml)" ] && check_geo Country.mmdb cn_mini.mmdb + #预下载GeoSite数据库并排除存在自定义数据库链接的情况 + [ -n "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && check_geo GeoSite.dat geosite.dat + #预下载cn.mrs数据库 + [ -n "$(cat "$CRASHDIR"/yamls/*.yaml | grep -oEi 'rule_set.*cn')" ] || [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && check_geo ruleset/cn.mrs mrs_geosite_cn.mrs + return 0 +} diff --git a/scripts/starts/clash_config_check.sh b/scripts/starts/clash_config_check.sh new file mode 100644 index 00000000..96e85c80 --- /dev/null +++ b/scripts/starts/clash_config_check.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# Copyright (C) Juewuy + +check_config() { #检查clash配置文件 + #检测节点或providers + sed -n "/^proxies:/,/^[a-z]/ { /^[a-z]/d; p; }" "$core_config_new" >"$TMPDIR"/proxies.yaml + if ! grep -Eq 'server:|server":|server'\'':' "$TMPDIR"/proxies.yaml && ! grep -q 'proxy-providers:' "$core_config_new"; then + echo "-----------------------------------------------" + logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31 + cat "$TMPDIR"/proxies.yaml + sleep 1 + echo "-----------------------------------------------" + echo "请尝试使用6-2或者6-3的方式生成配置文件!" + exit 1 + fi + rm -rf "$TMPDIR"/proxies.yaml + #检测旧格式 + if cat "$core_config_new" | grep 'Proxy Group:' >/dev/null; then + echo "-----------------------------------------------" + logger "已经停止对旧格式配置文件的支持!!!" 31 + echo -e "请使用新格式或者使用【在线生成配置文件】功能!" + echo "-----------------------------------------------" + exit 1 + fi + #检测不支持的加密协议 + if cat "$core_config_new" | grep 'cipher: chacha20,' >/dev/null; then + echo "-----------------------------------------------" + logger "已停止支持chacha20加密,请更换更安全的节点加密协议!" 31 + echo "-----------------------------------------------" + exit 1 + fi + #检测并去除无效策略组 + [ -n "$url_type" ] && ckcmd xargs && { + cat "$core_config_new" | sed '/^rules:/,$d' | grep -A 15 "\- name:" | xargs | sed 's/- name: /\n/g' | sed 's/ type: .*proxies: /#/g' | sed 's/- //g' | grep -E '#DIRECT $|#DIRECT$' | grep -Ev '全球直连|direct|Direct' | awk -F '#' '{print $1}' >"$TMPDIR"/clash_proxies + while read line; do + sed -i "/- $line/d" "$core_config_new" + sed -i "/- name: $line/,/- DIRECT/d" "$core_config_new" + done <"$TMPDIR"/clash_proxies + rm -rf "$TMPDIR"/clash_proxies + } +} \ No newline at end of file diff --git a/scripts/starts/clash_modify.sh b/scripts/starts/clash_modify.sh new file mode 100644 index 00000000..2a1f17b8 --- /dev/null +++ b/scripts/starts/clash_modify.sh @@ -0,0 +1,236 @@ +#!/bin/sh +# Copyright (C) Juewuy + +#默认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" +#修饰clash配置文件 +modify_yaml() { + ##########需要变更的配置########### + [ "$ipv6_dns" != "未开启" ] && dns_v6='true' || dns_v6='false' + external="external-controller: 0.0.0.0:$db_port" + if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ]; then + [ "$crashcore" = 'meta' ] && tun_meta=', device: utun, auto-route: false, auto-detect-interface: false' + tun="tun: {enable: true, stack: system$tun_meta}" + else + tun='tun: {enable: false}' + fi + exper='experimental: {ignore-resolve-fail: true, interface-name: en0}' + #Meta内核专属配置 + [ "$crashcore" = 'meta' ] && { + [ "$redir_mod" != "纯净模式" ] && [ -z "$(grep 'PROCESS' "$CRASHDIR"/yamls/*.yaml)" ] && find_process='find-process-mode: "off"' + } + #dns配置 + [ -z "$(cat "$CRASHDIR"/yamls/user.yaml 2>/dev/null | grep '^dns:')" ] && { + [ "$crashcore" != meta ] && dns_resolver='223.5.5.5' + cat >"$TMPDIR"/dns.yaml </dev/null | grep -v '#' | sed "s/^/ - '/" | sed "s/$/'/" >>"$TMPDIR"/dns.yaml + else + echo " - '+.*'" >>"$TMPDIR"/dns.yaml #使用fake-ip模拟redir_host + fi + #mix模式fakeip绕过cn + [ "$dns_mod" = "mix" ] && echo ' - "rule-set:cn"' >>"$TMPDIR"/dns.yaml + #mix模式和route模式插入分流设置 + if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then + [ "$dns_protect" != "OFF" ] && dns_final="$dns_fallback" || dns_final="$dns_nameserver" + cat >>"$TMPDIR"/dns.yaml <>"$TMPDIR"/dns.yaml <"$TMPDIR"/set.yaml </dev/null)" ]; then + #NTP劫持 + cat >"$TMPDIR"/hosts.yaml <>"$TMPDIR"/hosts.yaml + else + #加载本机hosts + sys_hosts=/etc/hosts + [ -f /data/etc/custom_hosts ] && sys_hosts=/data/etc/custom_hosts + while read line; do + [ -n "$(echo "$line" | grep -oE "([0-9]{1,3}[\.]){3}")" ] && + [ -z "$(echo "$line" | grep -oE '^#')" ] && + hosts_ip=$(echo $line | awk '{print $1}') && + hosts_domain=$(echo $line | awk '{print $2}') && + [ -z "$(cat "$TMPDIR"/hosts.yaml | grep -oE "$hosts_domain")" ] && + echo " '$hosts_domain': $hosts_ip" >>"$TMPDIR"/hosts.yaml + done <$sys_hosts + fi + fi + #分割配置文件 + yaml_char='proxies proxy-groups proxy-providers rules rule-providers sub-rules listeners' + for char in $yaml_char; do + sed -n "/^$char:/,/^[a-z]/ { /^[a-z]/d; p; }" $core_config >"$TMPDIR"/${char}.yaml + done + #跳过本地tls证书验证 + [ "$skip_cert" != "未开启" ] && sed -i 's/skip-cert-verify: false/skip-cert-verify: true/' "$TMPDIR"/proxies.yaml || + sed -i 's/skip-cert-verify: true/skip-cert-verify: false/' "$TMPDIR"/proxies.yaml + #插入自定义策略组 + sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml + sed -i "/#自定义策略组/d" "$TMPDIR"/proxy-groups.yaml + [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxy-groups.yaml 2>/dev/null)" ] && { + #获取空格数 + space_name=$(grep -aE '^ *- \{?name: ' "$TMPDIR"/proxy-groups.yaml | head -n 1 | grep -oE '^ *') + space_proxy="$space_name " + #合并自定义策略组到proxy-groups.yaml + cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml + cat "$TMPDIR"/proxy-groups.yaml >>"$TMPDIR"/proxy-groups_add.yaml + mv -f "$TMPDIR"/proxy-groups_add.yaml "$TMPDIR"/proxy-groups.yaml + oldIFS="$IFS" + grep "\- name: " "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | while read line; do #将自定义策略组插入现有的proxy-group + new_group=$(echo $line | grep -Eo '^ *- name:.*#' | cut -d'#' -f1 | sed 's/.*name: //g') + proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") + IFS="#" + for name in $proxy_groups; do + line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 + [ -n "$line_a" ] && { + line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 + line_c=$((line_a + line_b - 1)) #计算需要插入的行号 + space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 + [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${new_group} #自定义策略组" "$TMPDIR"/proxy-groups.yaml + } + done + IFS="$oldIFS" + done + } + #插入自定义代理 + sed -i "/#自定义代理/d" "$TMPDIR"/proxies.yaml + sed -i "/#自定义代理/d" "$TMPDIR"/proxy-groups.yaml + [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxies.yaml 2>/dev/null)" ] && { + space_proxy=$(cat "$TMPDIR"/proxies.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') #获取空格数 + cat "$CRASHDIR"/yamls/proxies.yaml | sed "s/^ *- /${space_proxy}- /g" | sed "/^#/d" | sed "/^ *$/d" | sed 's/#.*/ #自定义代理/g' >>"$TMPDIR"/proxies.yaml #插入节点 + oldIFS="$IFS" + cat "$CRASHDIR"/yamls/proxies.yaml | sed "/^#/d" | while read line; do #将节点插入proxy-group + proxy_name=$(echo $line | grep -Eo 'name: .+, ' | cut -d',' -f1 | sed 's/name: //g') + proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") + IFS="#" + for name in $proxy_groups; do + line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 + [ -n "$line_a" ] && { + line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 + line_c=$((line_a + line_b - 1)) #计算需要插入的行号 + space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 + [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${proxy_name} #自定义代理" "$TMPDIR"/proxy-groups.yaml + } + done + IFS="$oldIFS" + done + } + #添加自定义入站 + [ "$vms_service" = ON ] || [ "$sss_service" = ON ] && { + . "$CRASHDIR"/configs/gateway.cfg + . "$CRASHDIR"/libs/meta_listeners.sh + } + #节点绕过功能支持 + sed -i "/#节点绕过/d" "$TMPDIR"/rules.yaml + [ "$proxies_bypass" = "已启用" ] && { + cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '!a[$0]++' | sed 's/^/\ -\ IP-CIDR,/g' | sed 's|$|/32,DIRECT,no-resolve #节点绕过|g' >>"$TMPDIR"/proxies_bypass + cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -vE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?' | awk '!a[$0]++' | sed 's/^/\ -\ DOMAIN,/g' | sed 's/$/,DIRECT #节点绕过/g' >>"$TMPDIR"/proxies_bypass + cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/proxies_bypass + mv -f "$TMPDIR"/proxies_bypass "$TMPDIR"/rules.yaml + } + #插入自定义规则 + sed -i "/#自定义规则/d" "$TMPDIR"/rules.yaml + [ -s "$CRASHDIR"/yamls/rules.yaml ] && { + cat "$CRASHDIR"/yamls/rules.yaml | sed "/^#/d" | sed '$a\' | sed 's/$/ #自定义规则/g' >"$TMPDIR"/rules.add + cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/rules.add + mv -f "$TMPDIR"/rules.add "$TMPDIR"/rules.yaml + } + #mix和route模式生成rule-providers + [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && ! grep -q 'cn:' "$TMPDIR"/rule-providers.yaml && ! grep -q '^rule-providers' "$CRASHDIR"/yamls/others.yaml 2>/dev/null && { + space=$(sed -n "1p" "$TMPDIR"/rule-providers.yaml | grep -oE '^ *') #获取空格数 + [ -z "$space" ] && space=' ' + echo "${space}cn: {type: http, behavior: domain, format: mrs, path: ./ruleset/cn.mrs, url: https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@update/bin/geodata/mrs_geosite_cn.mrs}" >>"$TMPDIR"/rule-providers.yaml + } + #对齐rules中的空格 + sed -i 's/^ *-/ -/g' "$TMPDIR"/rules.yaml + #合并文件 + [ -s "$CRASHDIR"/yamls/user.yaml ] && { + yaml_user="$CRASHDIR"/yamls/user.yaml + #set和user去重,且优先使用user.yaml + cp -f "$TMPDIR"/set.yaml "$TMPDIR"/set_bak.yaml + for char in mode allow-lan log-level tun experimental external-ui-url interface-name dns store-selected; do + [ -n "$(grep -E "^$char" $yaml_user)" ] && sed -i "/^$char/d" "$TMPDIR"/set.yaml + done + } + [ -s "$TMPDIR"/dns.yaml ] && yaml_dns="$TMPDIR"/dns.yaml + [ -s "$TMPDIR"/hosts.yaml ] && yaml_hosts="$TMPDIR"/hosts.yaml + [ -s "$CRASHDIR"/yamls/others.yaml ] && yaml_others="$CRASHDIR"/yamls/others.yaml + yaml_add= + for char in $yaml_char; do #将额外配置文件合并 + [ -s "$TMPDIR"/${char}.yaml ] && { + sed -i "1i\\${char}:" "$TMPDIR"/${char}.yaml + yaml_add="$yaml_add $TMPDIR/${char}.yaml" + } + done + #合并完整配置文件 + cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_hosts $yaml_user $yaml_others $yaml_add >"$TMPDIR"/config.yaml + #测试自定义配置文件 + "$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml >/dev/null + if [ "$?" != 0 ]; then + logger "$("$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml | grep -Eo 'error.*=.*')" 31 + logger "自定义配置文件校验失败!将使用基础配置文件启动!" 33 + logger "错误详情请参考 "$TMPDIR"/error.yaml 文件!" 33 + mv -f "$TMPDIR"/config.yaml "$TMPDIR"/error.yaml >/dev/null 2>&1 + sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml + mv -f "$TMPDIR"/set_bak.yaml "$TMPDIR"/set.yaml >/dev/null 2>&1 + #合并基础配置文件 + cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_add >"$TMPDIR"/config.yaml + sed -i "/#自定义/d" "$TMPDIR"/config.yaml + fi + #建立软连接 + [ ""$TMPDIR"" = ""$BINDIR"" ] || ln -sf "$TMPDIR"/config.yaml "$BINDIR"/config.yaml 2>/dev/null || cp -f "$TMPDIR"/config.yaml "$BINDIR"/config.yaml + #清理缓存 + for char in $yaml_char set set_bak dns hosts; do + rm -f "$TMPDIR"/${char}.yaml + done +} \ No newline at end of file diff --git a/scripts/starts/core_config.sh b/scripts/starts/core_config.sh new file mode 100644 index 00000000..de1bd553 --- /dev/null +++ b/scripts/starts/core_config.sh @@ -0,0 +1,103 @@ +#!/bin/sh +# Copyright (C) Juewuy + +. "$CRASHDIR"/libs/urlencode.sh +. "$CRASHDIR"/libs/check_target.sh +. "$CRASHDIR"/libs/web_get_bin.sh +. "$CRASHDIR"/libs/compare.sh +. "$CRASHDIR"/libs/set_config.sh + +update_servers() { #更新servers.list + get_bin "$TMPDIR"/servers.list public/servers.list + [ "$?" = 0 ] && mv -f "$TMPDIR"/servers.list "$CRASHDIR"/configs/servers.list +} +gen_ua(){ #自动生成ua + [ -z "$user_agent" -o "$user_agent" = "auto" ] && { + if echo "$crashcore" | grep -q 'singbox'; then + user_agent="sing-box/singbox/$core_v" + elif [ "$crashcore" = meta ]; then + user_agent="clash.meta/mihomo/$core_v" + else + user_agent="clash" + fi + } + [ "$user_agent" = "none" ] && unset user_agent +} +get_core_config() { #下载内核配置文件 + [ -z "$rule_link" ] && rule_link=1 + [ -z "$server_link" ] || [ $server_link -gt $(grep -aE '^4' "$CRASHDIR"/configs/servers.list | wc -l) ] && server_link=1 + Server=$(grep -aE '^3|^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}') + Server_ua=$(grep -aE '^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $4}') + Config=$(grep -aE '^5' "$CRASHDIR"/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $3}') + gen_ua + #如果传来的是Url链接则合成Https链接,否则直接使用Https链接 + if [ -z "$Https" ]; then + #Urlencord转码处理保留字符 + if ckcmd hexdump;then + Url=$(echo $Url | sed 's/%26/\&/g') #处理分隔符 + urlencodeUrl="exclude=$(urlencode "$exclude")&include=$(urlencode "$include")&url=$(urlencode "$Url")&config=$(urlencode "$Config")" + else + urlencodeUrl="exclude=$exclude&include=$include&url=$Url&config=$Config" + fi + Https="${Server}/sub?target=${target}&${Server_ua}=${user_agent}&insert=true&new_name=true&scv=true&udp=true&${urlencodeUrl}" + url_type=true + fi + #输出 + echo "-----------------------------------------------" + logger "正在连接服务器获取【$target】配置文件…………" + echo -e "链接地址为:\033[4;32m$Https\033[0m" + echo 可以手动复制该链接到浏览器打开并查看数据是否正常! + #获取在线config文件 + core_config_new="$TMPDIR"/"$target"_config."$format" + rm -rf "$core_config_new" + webget "$core_config_new" "$Https" echoon rediron skipceron "$user_agent" + if [ "$?" != "0" ]; then + if [ -z "$url_type" ]; then + echo "-----------------------------------------------" + logger "配置文件获取失败!" 31 + echo -e "\033[31m请尝试使用【在线生成配置文件】功能!\033[0m" + echo "-----------------------------------------------" + exit 1 + else + if [ -n "$retry" ] && [ "$retry" -ge 3 ]; then + logger "无法获取配置文件,请检查链接格式以及网络连接状态!" 31 + echo -e "\033[32m也可用浏览器下载以上链接后,使用WinSCP手动上传到/tmp目录后执行crash命令本地导入!\033[0m" + exit 1 + else + retry=$((retry + 1)) + logger "配置文件获取失败!" 31 + if [ "$retry" = 1 ]; then + echo -e "\033[32m尝试更新服务器列表并使用其他服务器获取配置!\033[0m" + update_servers + else + echo -e "\033[32m尝试使用其他服务器获取配置!\033[0m" + fi + echo -e "正在重试\033[33m第$retry次/共3次!\033[0m" + if [ "$server_link" -ge 4 ]; then + server_link=0 + fi + server_link=$((server_link + 1)) + setconfig server_link $server_link + Https="" + get_core_config + fi + fi + else + Https="" + if echo "$crashcore" | grep -q 'singbox'; then + . "$CRASHDIR"/starts/singbox_config_check.sh + else + . "$CRASHDIR"/starts/clash_config_check.sh + fi + check_config + #如果不同则备份并替换文件 + if [ -s "$core_config" ]; then + compare "$core_config_new" "$core_config" + [ "$?" = 0 ] || mv -f "$core_config" "$core_config".bak && mv -f "$core_config_new" "$core_config" + else + mv -f "$core_config_new" "$core_config" + fi + echo -e "\033[32m已成功获取配置文件!\033[0m" + fi + return 0 +} diff --git a/scripts/starts/core_exchange.sh b/scripts/starts/core_exchange.sh new file mode 100644 index 00000000..c52ee5b6 --- /dev/null +++ b/scripts/starts/core_exchange.sh @@ -0,0 +1,11 @@ + +core_exchange() { #升级为高级内核 + #$1:目标内核 $2:提示语句 + logger "检测到${2}!将改为使用${1}核心启动!" 33 + rm -rf "$TMPDIR"/CrashCore + rm -rf "$BINDIR"/CrashCore + rm -rf "$BINDIR"/CrashCore.tar.gz + crashcore="$1" + setconfig crashcore "$1" + echo "-----------------------------------------------" +} diff --git a/scripts/starts/fw_getlanip.sh b/scripts/starts/fw_getlanip.sh new file mode 100644 index 00000000..61f10095 --- /dev/null +++ b/scripts/starts/fw_getlanip.sh @@ -0,0 +1,27 @@ + +getlanip() { #获取局域网host地址 + i=1 + while [ "$i" -le "20" ]; do + host_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Ev 'utun|iot|peer|docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g') #ipv4局域网网段 + [ "$ipv6_redir" = "已开启" ] && host_ipv6=$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g') #ipv6公网地址段 + [ -f "$TMPDIR"/ShellCrash.log ] && break + [ -n "$host_ipv4" -a "$ipv6_redir" != "已开启" ] && break + [ -n "$host_ipv4" -a -n "$host_ipv6" ] && break + sleep 1 && i=$((i + 1)) + done + #添加自定义ipv4局域网网段 + if [ "$replace_default_host_ipv4" == "已启用" ]; then + host_ipv4="$cust_host_ipv4" + else + host_ipv4="$host_ipv4$cust_host_ipv4" + fi + #缺省配置 + [ -z "$host_ipv4" ] && host_ipv4='192.168.0.0/16 10.0.0.0/12 172.16.0.0/12' + host_ipv6="fe80::/10 fd00::/8 $host_ipv6" + #获取本机出口IP地址 + local_ipv4=$(ip route 2>&1 | grep -Ev 'utun|iot|docker|linkdown' | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u) + [ -z "$local_ipv4" ] && local_ipv4=$(ip route 2>&1 | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u) + #保留地址 + [ -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" + [ -z "$reserve_ipv6" ] && reserve_ipv6="::/128 ::1/128 ::ffff:0:0/96 64:ff9b::/96 100::/64 2001::/32 2001:20::/28 2001:db8::/32 2002::/16 fe80::/10 ff00::/8" +} \ No newline at end of file diff --git a/scripts/starts/fw_iptables.sh b/scripts/starts/fw_iptables.sh index 763a4cec..689af4c0 100644 --- a/scripts/starts/fw_iptables.sh +++ b/scripts/starts/fw_iptables.sh @@ -130,6 +130,8 @@ start_ipt_dns() { #iptables-dns通用工具 "$1" $w -t nat -I "$2" -p udp --dport 53 -j "$3" } start_ipt_wan() { #iptables公网防火墙 + ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables + ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables ipt_wan_accept(){ $iptable -I INPUT -p "$1" -m multiport --dports "$fw_wan_ports" -j ACCEPT ckcmd ip6tables && $ip6table -I INPUT -p "$1" -m multiport --dports "$fw_wan_ports" -j ACCEPT diff --git a/scripts/starts/fw_start.sh b/scripts/starts/fw_start.sh index 8c06c82e..d0d34cae 100644 --- a/scripts/starts/fw_start.sh +++ b/scripts/starts/fw_start.sh @@ -1,42 +1,49 @@ #!/bin/sh # Copyright (C) Juewuy -#路由规则总入口 -start_firewall() { - getlanip #获取局域网host地址 - #设置策略路由 - [ "$firewall_area" != 4 ] && { - [ "$redir_mod" = "Tproxy模式" ] && ip route add local default dev lo table $table 2>/dev/null - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { - i=1 - while [ -z "$(ip route list | grep utun)" -a "$i" -le 29 ]; do - sleep 1 - i=$((i + 1)) - done - if [ -z "$(ip route list | grep utun)" ]; then - logger "找不到tun模块,放弃启动tun相关防火墙规则!" 31 - else - ip route add default dev utun table $table && tun_statu=true - fi - } - [ "$firewall_area" = 5 ] && ip route add default via $bypass_host table $table 2>/dev/null - [ "$redir_mod" != "Redir模式" ] && ip rule add fwmark $fwmark table $table 2>/dev/null - } - #添加ipv6路由 - [ "$ipv6_redir" = "已开启" -a "$firewall_area" -le 3 ] && { - [ "$redir_mod" = "Tproxy模式" ] && ip -6 route add local default dev lo table $((table + 1)) 2>/dev/null - [ -n "$(ip route list | grep utun)" ] && ip -6 route add default dev utun table $((table + 1)) 2>/dev/null - [ "$redir_mod" != "Redir模式" ] && ip -6 rule add fwmark $fwmark table $((table + 1)) 2>/dev/null - } - #判断代理用途 - [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && local_proxy=true - [ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 ] && lan_proxy=true - #防火墙配置 - [ "$firewall_mod" = 'iptables' ] && . "$CRASHDIR"/starts/fw_iptables.sh && start_iptables - [ "$firewall_mod" = 'nftables' ] && . "$CRASHDIR"/starts/fw_nftables.sh && start_nftables - #修复部分虚拟机dns查询失败的问题 - [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ "$systype" != 'container' ] && { - line=$(grep -n 'nameserver' /etc/resolv.conf | awk -F: 'FNR==1{print $1}') - sed -i "$line i\nameserver 127.0.0.1 #shellcrash-dns-repair" /etc/resolv.conf >/dev/null 2>&1 - } +#获取局域网host地址 +. "$CRASHDIR"/starts/fw_getlanip.sh && getlanip +#缺省值 +[ -z "$macfilter_type" ] && macfilter_type='黑名单' +[ -z "$common_ports" ] && common_ports='已开启' +[ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' +[ "$common_ports" = "已开启" ] && ports="-m multiport --dports $multiport" +[ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式' +[ -z "$dns_mod" ] && dns_mod='redir_host' +[ -z "$redir_mod" ] && firewall_area='4' + +#设置策略路由 +[ "$firewall_area" != 4 ] && { + [ "$redir_mod" = "Tproxy模式" ] && ip route add local default dev lo table $table 2>/dev/null + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { + i=1 + while [ -z "$(ip route list | grep utun)" -a "$i" -le 29 ]; do + sleep 1 + i=$((i + 1)) + done + if [ -z "$(ip route list | grep utun)" ]; then + logger "找不到tun模块,放弃启动tun相关防火墙规则!" 31 + else + ip route add default dev utun table $table && tun_statu=true + fi + } + [ "$firewall_area" = 5 ] && ip route add default via $bypass_host table $table 2>/dev/null + [ "$redir_mod" != "Redir模式" ] && ip rule add fwmark $fwmark table $table 2>/dev/null +} +#添加ipv6路由 +[ "$ipv6_redir" = "已开启" -a "$firewall_area" -le 3 ] && { + [ "$redir_mod" = "Tproxy模式" ] && ip -6 route add local default dev lo table $((table + 1)) 2>/dev/null + [ -n "$(ip route list | grep utun)" ] && ip -6 route add default dev utun table $((table + 1)) 2>/dev/null + [ "$redir_mod" != "Redir模式" ] && ip -6 rule add fwmark $fwmark table $((table + 1)) 2>/dev/null +} +#判断代理用途 +[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && local_proxy=true +[ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 ] && lan_proxy=true +#防火墙配置 +[ "$firewall_mod" = 'iptables' ] && . "$CRASHDIR"/starts/fw_iptables.sh && start_iptables +[ "$firewall_mod" = 'nftables' ] && . "$CRASHDIR"/starts/fw_nftables.sh && start_nftables +#修复部分虚拟机dns查询失败的问题 +[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ "$systype" != 'container' ] && { + line=$(grep -n 'nameserver' /etc/resolv.conf | awk -F: 'FNR==1{print $1}') + sed -i "$line i\nameserver 127.0.0.1 #shellcrash-dns-repair" /etc/resolv.conf >/dev/null 2>&1 } diff --git a/scripts/starts/fw_stop.sh b/scripts/starts/fw_stop.sh index 7152bca7..b380b5b5 100644 --- a/scripts/starts/fw_stop.sh +++ b/scripts/starts/fw_stop.sh @@ -1,130 +1,136 @@ #!/bin/sh # Copyright (C) Juewuy + #还原防火墙配置 -stop_firewall() { - #获取局域网host地址 - getlanip - #重置iptables相关规则 - ckcmd iptables && { - #dns - $iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_dns 2>/dev/null - $iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_dns 2>/dev/null - $iptable -t nat -D OUTPUT -p udp --dport 53 -j shellcrash_dns_out 2>/dev/null - $iptable -t nat -D OUTPUT -p tcp --dport 53 -j shellcrash_dns_out 2>/dev/null - #redir - $iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash 2>/dev/null - $iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash 2>/dev/null - $iptable -t nat -D OUTPUT -p tcp $ports -j shellcrash_out 2>/dev/null - $iptable -t nat -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_out 2>/dev/null - #vm_dns - $iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_vm_dns 2>/dev/null - $iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_vm_dns 2>/dev/null - #vm_redir - $iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash_vm 2>/dev/null - $iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_vm 2>/dev/null - #TPROXY&tun - $iptable -t mangle -D PREROUTING -p tcp $ports -j shellcrash_mark 2>/dev/null - $iptable -t mangle -D PREROUTING -p udp $ports -j shellcrash_mark 2>/dev/null - $iptable -t mangle -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null - $iptable -t mangle -D PREROUTING -p udp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null - $iptable -t mangle -D OUTPUT -p tcp $ports -j shellcrash_mark_out 2>/dev/null - $iptable -t mangle -D OUTPUT -p udp $ports -j shellcrash_mark_out 2>/dev/null - $iptable -t mangle -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null - $iptable -t mangle -D OUTPUT -p udp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null - $iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null - $iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null - #tun - $iptable -D FORWARD -o utun -j ACCEPT 2>/dev/null - #屏蔽QUIC - [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && set_cn_ip='-m set ! --match-set cn_ip dst' - $iptable -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null - $iptable -D FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT 2>/dev/null - #公网访问 - $iptable -D INPUT -i lo -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null - $iptable -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - $iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - #清理shellcrash自建表 - for words in shellcrash_dns shellcrash shellcrash_out shellcrash_dns_out shellcrash_vm shellcrash_vm_dns; do - $iptable -t nat -F $words 2>/dev/null - $iptable -t nat -X $words 2>/dev/null - done - for words in shellcrash_mark shellcrash_mark_out; do - $iptable -t mangle -F $words 2>/dev/null - $iptable -t mangle -X $words 2>/dev/null - done - } - #重置ipv6规则 - ckcmd ip6tables && { - #dns - $ip6table -t nat -D PREROUTING -p tcp --dport 53 -j shellcrashv6_dns 2>/dev/null - $ip6table -t nat -D PREROUTING -p udp --dport 53 -j shellcrashv6_dns 2>/dev/null - #redir - $ip6table -t nat -D PREROUTING -p tcp $ports -j shellcrashv6 2>/dev/null - $ip6table -t nat -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6 2>/dev/null - $ip6table -t nat -D OUTPUT -p tcp $ports -j shellcrashv6_out 2>/dev/null - $ip6table -t nat -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_out 2>/dev/null - $ip6table -D INPUT -p tcp --dport 53 -j REJECT 2>/dev/null - $ip6table -D INPUT -p udp --dport 53 -j REJECT 2>/dev/null - #mark - $ip6table -t mangle -D PREROUTING -p tcp $ports -j shellcrashv6_mark 2>/dev/null - $ip6table -t mangle -D PREROUTING -p udp $ports -j shellcrashv6_mark 2>/dev/null - $ip6table -t mangle -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null - $ip6table -t mangle -D PREROUTING -p udp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null - $ip6table -t mangle -D OUTPUT -p tcp $ports -j shellcrashv6_mark_out 2>/dev/null - $ip6table -t mangle -D OUTPUT -p udp $ports -j shellcrashv6_mark_out 2>/dev/null - $ip6table -t mangle -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null - $ip6table -t mangle -D OUTPUT -p udp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null - $ip6table -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null - $ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null - $ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null - #tun - $ip6table -D FORWARD -o utun -j ACCEPT 2>/dev/null - #屏蔽QUIC - [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && set_cn_ip6='-m set ! --match-set cn_ip6 dst' - $ip6table -D INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT 2>/dev/null - $ip6table -D FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT 2>/dev/null - #公网访问 - $ip6table -D INPUT -i lo -j ACCEPT 2>/dev/null - $ip6table -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null - $ip6table -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null - $ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - $ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null - #清理shellcrash自建表 - for words in shellcrashv6_dns shellcrashv6 shellcrashv6_out; do - $ip6table -t nat -F $words 2>/dev/null - $ip6table -t nat -X $words 2>/dev/null - done - for words in shellcrashv6_mark shellcrashv6_mark_out; do - $ip6table -t mangle -F $words 2>/dev/null - $ip6table -t mangle -X $words 2>/dev/null - done - $ip6table -t mangle -F shellcrashv6_mark 2>/dev/null - $ip6table -t mangle -X shellcrashv6_mark 2>/dev/null - } - #清理ipset规则 - ipset destroy cn_ip >/dev/null 2>&1 - ipset destroy cn_ip6 >/dev/null 2>&1 - #移除dnsmasq转发规则 - [ "$dns_redir" = "已开启" ] && { - uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 - uci set dhcp.@dnsmasq[0].noresolv=0 2>/dev/null - uci commit dhcp >/dev/null 2>&1 - /etc/init.d/dnsmasq restart >/dev/null 2>&1 - } - #清理路由规则 - ip rule del fwmark $fwmark table $table 2>/dev/null - ip route flush table $table 2>/dev/null - ip -6 rule del fwmark $fwmark table $((table + 1)) 2>/dev/null - ip -6 route flush table $((table + 1)) 2>/dev/null - #重置nftables相关规则 - ckcmd nft && { - nft flush table inet shellcrash >/dev/null 2>&1 - nft delete table inet shellcrash >/dev/null 2>&1 - } - #还原防火墙文件 - [ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall - #others - [ "$systype" != 'container' ] && sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf >/dev/null 2>&1 +. "$CRASHDIR"/configs/ShellCrash.cfg +. "$CRASHDIR"/starts/fw_getlanip.sh && getlanip #获取局域网host地址 +#缺省值 +[ -z "$common_ports" ] && common_ports='已开启' +[ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' +[ "$common_ports" = "已开启" ] && ports="-m multiport --dports $multiport" +#重置iptables相关规则 +ckcmd iptables && { + ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables + #dns + $iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_dns 2>/dev/null + $iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_dns 2>/dev/null + $iptable -t nat -D OUTPUT -p udp --dport 53 -j shellcrash_dns_out 2>/dev/null + $iptable -t nat -D OUTPUT -p tcp --dport 53 -j shellcrash_dns_out 2>/dev/null + #redir + $iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash 2>/dev/null + $iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash 2>/dev/null + $iptable -t nat -D OUTPUT -p tcp $ports -j shellcrash_out 2>/dev/null + $iptable -t nat -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_out 2>/dev/null + #vm_dns + $iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_vm_dns 2>/dev/null + $iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_vm_dns 2>/dev/null + #vm_redir + $iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash_vm 2>/dev/null + $iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_vm 2>/dev/null + #TPROXY&tun + $iptable -t mangle -D PREROUTING -p tcp $ports -j shellcrash_mark 2>/dev/null + $iptable -t mangle -D PREROUTING -p udp $ports -j shellcrash_mark 2>/dev/null + $iptable -t mangle -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null + $iptable -t mangle -D PREROUTING -p udp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null + $iptable -t mangle -D OUTPUT -p tcp $ports -j shellcrash_mark_out 2>/dev/null + $iptable -t mangle -D OUTPUT -p udp $ports -j shellcrash_mark_out 2>/dev/null + $iptable -t mangle -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null + $iptable -t mangle -D OUTPUT -p udp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null + $iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null + $iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null + #tun + $iptable -D FORWARD -o utun -j ACCEPT 2>/dev/null + #屏蔽QUIC + [ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" != "未开启" ] && set_cn_ip='-m set ! --match-set cn_ip dst' + $iptable -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null + $iptable -D FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT 2>/dev/null + #公网访问 + $iptable -D INPUT -i lo -j ACCEPT 2>/dev/null + $iptable -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null + $iptable -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null + $iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + $iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + #清理shellcrash自建表 + for text in shellcrash_dns shellcrash shellcrash_out shellcrash_dns_out shellcrash_vm shellcrash_vm_dns; do + $iptable -t nat -F "$text" 2>/dev/null + $iptable -t nat -X "$text" 2>/dev/null + done + for text in shellcrash_mark shellcrash_mark_out; do + $iptable -t mangle -F "$text" 2>/dev/null + $iptable -t mangle -X "$text" 2>/dev/null + done } +#重置ipv6规则 +ckcmd ip6tables && { + ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables + #dns + $ip6table -t nat -D PREROUTING -p tcp --dport 53 -j shellcrashv6_dns 2>/dev/null + $ip6table -t nat -D PREROUTING -p udp --dport 53 -j shellcrashv6_dns 2>/dev/null + #redir + $ip6table -t nat -D PREROUTING -p tcp $ports -j shellcrashv6 2>/dev/null + $ip6table -t nat -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6 2>/dev/null + $ip6table -t nat -D OUTPUT -p tcp $ports -j shellcrashv6_out 2>/dev/null + $ip6table -t nat -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_out 2>/dev/null + $ip6table -D INPUT -p tcp --dport 53 -j REJECT 2>/dev/null + $ip6table -D INPUT -p udp --dport 53 -j REJECT 2>/dev/null + #mark + $ip6table -t mangle -D PREROUTING -p tcp $ports -j shellcrashv6_mark 2>/dev/null + $ip6table -t mangle -D PREROUTING -p udp $ports -j shellcrashv6_mark 2>/dev/null + $ip6table -t mangle -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null + $ip6table -t mangle -D PREROUTING -p udp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null + $ip6table -t mangle -D OUTPUT -p tcp $ports -j shellcrashv6_mark_out 2>/dev/null + $ip6table -t mangle -D OUTPUT -p udp $ports -j shellcrashv6_mark_out 2>/dev/null + $ip6table -t mangle -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null + $ip6table -t mangle -D OUTPUT -p udp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null + $ip6table -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null + $ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null + $ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null + #tun + $ip6table -D FORWARD -o utun -j ACCEPT 2>/dev/null + #屏蔽QUIC + [ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" != "未开启" ] && set_cn_ip6='-m set ! --match-set cn_ip6 dst' + $ip6table -D INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT 2>/dev/null + $ip6table -D FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT 2>/dev/null + #公网访问 + $ip6table -D INPUT -i lo -j ACCEPT 2>/dev/null + $ip6table -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null + $ip6table -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null + $ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + $ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null + #清理shellcrash自建表 + for text in shellcrashv6_dns shellcrashv6 shellcrashv6_out; do + $ip6table -t nat -F "$text" 2>/dev/null + $ip6table -t nat -X "$text" 2>/dev/null + done + for text in shellcrashv6_mark shellcrashv6_mark_out; do + $ip6table -t mangle -F "$text" 2>/dev/null + $ip6table -t mangle -X "$text" 2>/dev/null + done + $ip6table -t mangle -F shellcrashv6_mark 2>/dev/null + $ip6table -t mangle -X shellcrashv6_mark 2>/dev/null +} +#清理ipset规则 +ipset destroy cn_ip >/dev/null 2>&1 +ipset destroy cn_ip6 >/dev/null 2>&1 +#移除dnsmasq转发规则 +[ "$dns_redir" = "已开启" ] && { + uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 + uci set dhcp.@dnsmasq[0].noresolv=0 2>/dev/null + uci commit dhcp >/dev/null 2>&1 + /etc/init.d/dnsmasq restart >/dev/null 2>&1 +} +#清理路由规则 +ip rule del fwmark $fwmark table $table 2>/dev/null +ip route flush table $table 2>/dev/null +ip -6 rule del fwmark $fwmark table $((table + 1)) 2>/dev/null +ip -6 route flush table $((table + 1)) 2>/dev/null +#重置nftables相关规则 +ckcmd nft && { + nft flush table inet shellcrash >/dev/null 2>&1 + nft delete table inet shellcrash >/dev/null 2>&1 +} +#还原防火墙文件 +[ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall +#others +[ "$systype" != 'container' ] && sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf >/dev/null 2>&1 + diff --git a/scripts/starts/general_init.sh b/scripts/starts/general_init.sh new file mode 100644 index 00000000..b34b2c7b --- /dev/null +++ b/scripts/starts/general_init.sh @@ -0,0 +1,34 @@ +#!/bin/sh +# Copyright (C) Juewuy + +#初始化目录 +CRASHDIR=$( + cd $(dirname $0) + cd .. + pwd +) +profile=/etc/profile +. "$CRASHDIR"/libs/set_profile.sh +. "$CRASHDIR"/libs/set_cron.sh +. "$CRASHDIR"/configs/ShellCrash.cfg +#padavan和华硕环境变量目录设置 +if [ -d "/etc/storage/clash" -o -d "/etc/storage/ShellCrash" ]; then + i=1 + while [ ! -w /etc/profile -a "$i" -lt 10 ]; do + sleep 3 && i=$((i + 1)) + done + [ -w "$profile" ] || profile=/etc_ro/profile + mount -t tmpfs -o remount,rw,size=45M tmpfs /tmp #增加/tmp空间以适配新的内核压缩方式 + sed -i '' "$profile" #将软链接转化为一般文件 +elif [ -d "/jffs" ]; then + sleep 60 + [ -w "$profile" ] || profile=$(cat /etc/profile | grep -oE '\-f.*jffs.*profile' | awk '{print $2}') +fi +#写入环境变量 +set_profile "$profile" +#启动进程或删除守护进程 +if [ -f "$CRASHDIR"/.dis_startup ];then + cronset "保守模式守护进程" +else + "$CRASHDIR"/start.sh start +fi diff --git a/scripts/starts/shellcrash.openrc b/scripts/starts/shellcrash.openrc deleted file mode 100644 index a0b21567..00000000 --- a/scripts/starts/shellcrash.openrc +++ /dev/null @@ -1,73 +0,0 @@ -#!/sbin/openrc-run - -# 服务名 -name="shellcrash" -description="Custom proxy service for ShellCrash" -#获取目录 -CRASHDIR=$(cat /etc/profile | grep CRASHDIR | awk -F "\"" '{print $2}') -[ -z "$CRASHDIR" ] && CRASHDIR=$(cat ~/.bashrc | grep CRASHDIR | awk -F "\"" '{print $2}') -source ${CRASHDIR}/configs/command.env #加载启动命令和启动目录 - -# PID 文件 -pidfile="/run/shellcrash.pid" - -depend() { - #need net - after firewall -} - -start() { - ebegin "Starting ShellCrash service" - - # 如果 firewal_area=5 则运行主旁转发脚本 - if grep -q 'firewall_area=5' "$CRASHDIR/configs/ShellCrash.cfg" 2>/dev/null; then - "$CRASHDIR/start.sh" start_firewall - eend $? "Firewall start failed" - return - fi - - # 确定运行用户:shellcrash 或 root - if grep -q 'shellcrash:x:0:7890' /etc/passwd; then - runuser="shellcrash" - else - runuser="root" - fi - - # 必要文件检测 - "$CRASHDIR/start.sh" bfstart - if [ "$?" != "0" ]; then - eend 1 "bfstart check failed" - return - fi - - # 启动主程序(自动守护 + 自动重启) - supervise-daemon "${name}" \ - --pidfile "${pidfile}" \ - --user "${runuser}" \ - --respawn-max 0 \ - --respawn-delay 3 \ - --start ${COMMAND%% *} -- ${COMMAND#* } - - ret=$? - eend $ret - [ $ret -ne 0 ] && return - - # 启动后操作 - "$CRASHDIR/start.sh" afstart & -} - -stop() { - ebegin "Stopping ShellCrash service" - - # 停止后台进程 - start-stop-daemon --stop \ - --pidfile "${pidfile}" \ - --retry 5 - - rm -f "${pidfile}" - - # 清理 firewall、proxy - "$CRASHDIR/start.sh" stop_firewall - - eend $? -} diff --git a/scripts/starts/shellcrash.procd b/scripts/starts/shellcrash.procd deleted file mode 100644 index f884dd10..00000000 --- a/scripts/starts/shellcrash.procd +++ /dev/null @@ -1,38 +0,0 @@ -#!/bin/sh /etc/rc.common - -START=99 - -SERVICE_DAEMONIZE=1 -SERVICE_WRITE_PID=1 -USE_PROCD=1 -#获取目录 -CRASHDIR=$(cat /etc/profile | grep CRASHDIR | awk -F "\"" '{print $2}') -[ -z "$CRASHDIR" ] && CRASHDIR=$(cat ~/.bashrc | grep CRASHDIR | awk -F "\"" '{print $2}') -source ${CRASHDIR}/configs/command.env #加载启动命令和启动目录 - -start_service() { - if [ -n "$(cat $CRASHDIR/configs/ShellCrash.cfg | grep 'firewall_area=5')" ]; then - $CRASHDIR/start.sh start_firewall #主旁转发 - else - #本机代理用户 - [ -n "$(grep 'shellcrash:x:0:7890' /etc/passwd)" ] && USER=shellcrash || USER=root - #检测必须文件 - $CRASHDIR/start.sh bfstart - if [ "$?" = "0" ]; then - #使用procd创建clash后台进程 - procd_open_instance - procd_set_param user $USER - procd_set_param respawn - procd_set_param command $COMMAND - procd_set_param stderr 0 - procd_set_param stdout 0 - procd_close_instance - #启动结束执行 - $CRASHDIR/start.sh afstart & - fi - fi -} -stop_service() { - procd_close_instance - $CRASHDIR/start.sh stop_firewall -} diff --git a/scripts/starts/shellcrash.service b/scripts/starts/shellcrash.service deleted file mode 100644 index ac2bc3c0..00000000 --- a/scripts/starts/shellcrash.service +++ /dev/null @@ -1,20 +0,0 @@ -[Unit] -Description=ShellCrash Core -After=network.target - -[Service] -Type=simple -User=shellcrash -User=shellcrash -StandardOutput=null -ExecStartPre=/etc/ShellCrash/start.sh bfstart -ExecStart=/etc/ShellCrash/CrashCore run -D /etc/ShellCrash -C /tmp/ShellCrash/jsons >/dev/null -ExecStartPost=/etc/ShellCrash/start.sh afstart -ExecStopPost=/etc/ShellCrash/start.sh stop_firewall -Restart=on-abnormal -RestartSec=10s -LimitNOFILE=infinity - - -[Install] -WantedBy=multi-user.target diff --git a/scripts/starts/singbox_check.sh b/scripts/starts/singbox_check.sh new file mode 100644 index 00000000..31ff40bb --- /dev/null +++ b/scripts/starts/singbox_check.sh @@ -0,0 +1,13 @@ + +singbox_check() { #singbox启动前检查 + #检测singboxr专属功能 + [ "$crashcore" != "singboxr" ] && [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oE '"shadowsocksr"|"providers"')" ] && { + . "$CRASHDIR"/starts/core_exchange.sh && core_exchange singboxr 'singboxr内核专属功能' + } + check_core + #预下载geoip-cn.srs数据库 + [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"geoip-cn"')" ] && check_geo ruleset/geoip-cn.srs srs_geoip_cn.srs + #预下载cn.srs数据库 + [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"cn"')" ] || [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && check_geo ruleset/cn.srs srs_geosite_cn.srs + return 0 +} \ No newline at end of file diff --git a/scripts/starts/singbox_config_check.sh b/scripts/starts/singbox_config_check.sh new file mode 100644 index 00000000..d4b1731d --- /dev/null +++ b/scripts/starts/singbox_config_check.sh @@ -0,0 +1,37 @@ +#!/bin/sh +# Copyright (C) Juewuy + +check_config() { #检查singbox配置文件 + #检测节点或providers + if ! grep -qE '"(socks|http|shadowsocks(r)?|vmess|trojan|wireguard|hysteria(2)?|vless|shadowtls|tuic|ssh|tor|providers|anytls|soduku)"' "$core_config_new"; then + echo "-----------------------------------------------" + logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31 + echo "请尝试使用6-2或者6-3的方式生成配置文件!" + exit 1 + fi + #删除不兼容的旧版内容 + [ "$(wc -l <"$core_config_new")" -lt 3 ] && { + sed -i 's/^.*"inbounds":/{"inbounds":/' "$core_config_new" + sed -i 's/{[^{}]*"dns-out"[^{}]*}//g' "$core_config_new" + } + #检查不支持的旧版内容 + grep -q '"sni"' "$core_config_new" && { + logger "获取到了不支持的旧版(<1.12)配置文件【$core_config_new】!" 31 + echo "请尝试使用支持1.12以上版本内核的方式生成配置文件!" + exit 1 + } + #检测并去除无效策略组 + [ -n "$url_type" ] && { + #获得无效策略组名称 + grep -oE '\{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]' "$core_config_new" | sed -n 's/.*"tag":"\([^"]*\)".*/\1/p' >"$TMPDIR"/singbox_tags + #删除策略组 + sed -i 's/{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]}//g; s/{"type":"[^"]*","tag":"[^"]*","outbounds":\["DIRECT"\],"url":"[^"]*","interval":"[^"]*","tolerance":[^}]*}//g' "$core_config_new" + #删除全部包含策略组名称的规则 + while read line; do + sed -i "s/\"$line\"//g" "$core_config_new" + done <"$TMPDIR"/singbox_tags + rm -rf "$TMPDIR"/singbox_tags + } + #清理多余逗号 + sed -i 's/,\+/,/g; s/\[,/\[/g; s/,]/]/g' "$core_config_new" +} diff --git a/scripts/starts/singbox_modify.sh b/scripts/starts/singbox_modify.sh new file mode 100644 index 00000000..b96fc17f --- /dev/null +++ b/scripts/starts/singbox_modify.sh @@ -0,0 +1,387 @@ +#!/bin/sh +# Copyright (C) Juewuy + +#默认dns +[ -z "$dns_nameserver" ] && dns_nameserver='223.5.5.5' +[ -z "$dns_fallback" ] && dns_fallback="1.1.1.1" +[ -z "$dns_resolver" ] && dns_resolver="223.5.5.5" + #修饰singbox配置文件 +parse_singbox_dns() { #dns转换 + first_dns=$(echo "$1" | cut -d',' -f1 | cut -d' ' -f1) + type="" + server="" + port="" + case "$first_dns" in + *://*) + type="${first_dns%%://*}" + tmp="${first_dns#*://}" + ;; + *) + type="udp" + tmp="$first_dns" + ;; + esac + case "$tmp" in + \[*\]*) + server="${tmp%%]*}" + server="${server#[}" + port="${tmp#*\]}" + port="${port#:}" + ;; + *) + server="${tmp%%[:/]*}" + port="${tmp#*:}" + [ "$port" = "$tmp" ] && port="" + ;; + esac + if [ -z "$port" ]; then + case "$type" in + udp|tcp) port=53 ;; + doh|https) port=443 ;; + dot|tls) port=853 ;; + *) port=53 ;; + esac + fi + # 输出 + echo '"type": "'"$type"'", "server": "'"$server"'", "server_port": '"$port"',' +} +modify_json() { + #提取配置文件以获得outbounds.json,providers.json及route.json + "$TMPDIR"/CrashCore format -c $core_config >"$TMPDIR"/format.json + echo '{' >"$TMPDIR"/jsons/outbounds.json + echo '{' >"$TMPDIR"/jsons/route.json + cat "$TMPDIR"/format.json | sed -n '/"outbounds":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/outbounds.json + [ "$crashcore" = "singboxr" ] && { + echo '{' >"$TMPDIR"/jsons/providers.json + cat "$TMPDIR"/format.json | sed -n '/^ "providers":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/providers.json + } + cat "$TMPDIR"/format.json | sed -n '/"route":/,/^\( "[a-z]\|}\)/p' | sed '$d' >>"$TMPDIR"/jsons/route.json + #生成endpoints.json + [ "$ts_service" = ON ] || [ "$wg_service" = ON ] && { + . "$CRASHDIR"/configs/gateway.cfg + . "$CRASHDIR"/libs/sb_endpoints.sh + } + #生成log.json + cat >"$TMPDIR"/jsons/log.json <"$TMPDIR"/jsons/add_hosts.json </dev/null | grep -Ev '#|\*|\+|Mijia' | sed '/^\s*$/d' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') + fake_ip_filter_suffix=$(cat ${CRASHDIR}/configs/fake_ip_filter ${CRASHDIR}/configs/fake_ip_filter.list 2>/dev/null | grep -v '.\*' | grep -E '\*|\+' | sed 's/^[*+]\.//' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') + fake_ip_filter_regex=$(cat ${CRASHDIR}/configs/fake_ip_filter ${CRASHDIR}/configs/fake_ip_filter.list 2>/dev/null | grep '.\*' | sed 's/\./\\\\./g' | sed 's/\*/.\*/' | sed 's/^+/.\+/' | awk '{printf "\"%s\", ",$1}' | sed 's/, $//') + [ -n "$fake_ip_filter_domain" ] && fake_ip_filter_domain="{ \"domain\": [$fake_ip_filter_domain], \"server\": \"dns_direct\" }," + [ -n "$fake_ip_filter_suffix" ] && fake_ip_filter_suffix="{ \"domain_suffix\": [$fake_ip_filter_suffix], \"server\": \"dns_direct\" }," + [ -n "$fake_ip_filter_regex" ] && fake_ip_filter_regex="{ \"domain_regex\": [$fake_ip_filter_regex], \"server\": \"dns_direct\" }," + proxy_dns='{ "query_type": ["A", "AAAA"], "server": "dns_fakeip", "strategy": "'"$strategy"'", "rewrite_ttl": 1 }' + #mix模式插入fakeip过滤规则 + [ "$dns_mod" = "mix" ] && direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" },' + } + [ "$dns_mod" = "route" ] && { + global_dns=dns_proxy + direct_dns='{ "rule_set": ["cn"], "server": "dns_direct" }' + } + #防泄露设置 + [ "$dns_protect" = "OFF" ] && sed -i 's/"server": "dns_proxy"/"server": "dns_direct"/g' "$TMPDIR"/jsons/route.json + #生成add_rule_set.json + [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && + [ -z "$(cat "$CRASHDIR"/jsons/*.json | grep -Ei '"tag" *: *"cn"')" ] && + cat >"$TMPDIR"/jsons/add_rule_set.json <"$TMPDIR"/jsons/dns.json <"$TMPDIR"/jsons/add_route.json <"$TMPDIR"/jsons/certificate.json <"$TMPDIR"/jsons/inbounds.json <>"$TMPDIR"/jsons/tun.json <"$TMPDIR"/jsons/add_outbounds.json <"$TMPDIR"/jsons/experimental.json </dev/null)" ] && { + cat "$CRASHDIR"/yamls/rules.yaml | + sed '/#.*/d' | + sed 's/,no-resolve//g' | + grep -oE '\-.*,.*,.*' | + sed 's/- DOMAIN-SUFFIX,/{ "domain_suffix": [ "/g' | + sed 's/- DOMAIN-KEYWORD,/{ "domain_keyword": [ "/g' | + sed 's/- IP-CIDR,/{ "ip_cidr": [ "/g' | + sed 's/- SRC-IP-CIDR,/{ "._ip_cidr": [ "/g' | + sed 's/- DST-PORT,/{ "port": [ "/g' | + sed 's/- SRC-PORT,/{ "._port": [ "/g' | + sed 's/- GEOIP,/{ "geoip": [ "/g' | + sed 's/- GEOSITE,/{ "geosite": [ "/g' | + sed 's/- IP-CIDR6,/{ "ip_cidr": [ "/g' | + sed 's/- DOMAIN,/{ "domain": [ "/g' | + sed 's/- PROCESS-NAME,/{ "process_name": [ "/g' | + sed 's/,/" ], "outbound": "/g' | + sed 's/$/" },/g' | + sed '1i\{ "route": { "rules": [ ' | + sed '$s/,$/ ] } }/' >"$TMPDIR"/jsons/cust_add_rules.json + [ ! -s "$TMPDIR"/jsons/cust_add_rules.json ] && rm -rf "$TMPDIR"/jsons/cust_add_rules.json + } + #清理route.json中的process_name规则以及"auto_detect_interface" + sed -i '/"process_name": \[/,/],$/d' "$TMPDIR"/jsons/route.json + sed -i '/"process_name": "[^"]*",/d' "$TMPDIR"/jsons/route.json + sed -i 's/"auto_detect_interface": true/"auto_detect_interface": false/g' "$TMPDIR"/jsons/route.json + #跳过本地tls证书验证 + if [ "$skip_cert" != "未开启" ]; then + sed -i 's/"insecure": false/"insecure": true/' "$TMPDIR"/jsons/outbounds.json "$TMPDIR"/jsons/providers.json 2>/dev/null + else + sed -i 's/"insecure": true/"insecure": false/' "$TMPDIR"/jsons/outbounds.json "$TMPDIR"/jsons/providers.json 2>/dev/null + fi + #判断可用并修饰outbounds&providers&route.json结尾 + for file in outbounds providers route; do + if [ -n "$(grep ${file} "$TMPDIR"/jsons/${file}.json 2>/dev/null)" ]; then + sed -i 's/^ },$/ }/; s/^ ],$/ ]/' "$TMPDIR"/jsons/${file}.json + echo '}' >>"$TMPDIR"/jsons/${file}.json + else + rm -rf "$TMPDIR"/jsons/${file}.json + fi + done + #加载自定义配置文件 + mkdir -p "$TMPDIR"/jsons_base + #以下为覆盖脚本的自定义文件 + for char in log dns ntp certificate experimental; do + [ -s "$CRASHDIR"/jsons/${char}.json ] && { + ln -sf "$CRASHDIR"/jsons/${char}.json "$TMPDIR"/jsons/cust_${char}.json + mv -f "$TMPDIR"/jsons/${char}.json "$TMPDIR"/jsons_base #如果重复则临时备份 + } + done + #以下为增量添加的自定义文件 + for char in others endpoints inbounds outbounds providers route services; do + [ -s "$CRASHDIR"/jsons/${char}.json ] && { + ln -sf "$CRASHDIR"/jsons/${char}.json "$TMPDIR"/jsons/cust_${char}.json + } + done + #测试自定义配置文件 + if ! error=$("$TMPDIR"/CrashCore check -D "$BINDIR" -C "$TMPDIR"/jsons 2>&1); then + echo $error + error_file=$(echo $error | grep -Eo 'cust.*\.json' | sed 's/cust_//g') + [ "$error_file" = 'add_rules.json' ] && error_file="$CRASHDIR"/yamls/rules.yaml自定义规则 || error_file="$CRASHDIR"/jsons/$error_file + logger "自定义配置文件校验失败,请检查【${error_file}】文件!" 31 + logger "尝试使用基础配置文件启动~" 33 + #清理自定义配置文件并还原基础配置 + rm -rf "$TMPDIR"/jsons/cust_* + mv -f "$TMPDIR"/jsons_base/* "$TMPDIR"/jsons 2>/dev/null + fi + #清理缓存 + rm -rf "$TMPDIR"/*.json + rm -rf "$TMPDIR"/jsons_base + return 0 +} diff --git a/scripts/starts/snapshot_init.sh b/scripts/starts/snapshot_init.sh deleted file mode 100644 index 8a1a69d4..00000000 --- a/scripts/starts/snapshot_init.sh +++ /dev/null @@ -1,94 +0,0 @@ -#!/bin/sh -# Copyright (C) Juewuy - -CRASHDIR="$(uci get firewall.ShellCrash.path | sed 's/\/misnap_init.sh//')" -profile=/etc/profile -. "$CRASHDIR"/configs/ShellCrash.cfg - -autoSSH(){ - #自动开启SSH - [ "`uci -c /usr/share/xiaoqiang get xiaoqiang_version.version.CHANNEL`" != 'stable' ] && { - uci -c /usr/share/xiaoqiang set xiaoqiang_version.version.CHANNEL='stable' - uci -c /usr/share/xiaoqiang commit xiaoqiang_version.version - } - [ -z "$(pidof dropbear)" -o -z "$(netstat -ntul | grep :22)" ] && { - sed -i 's/channel=.*/channel="debug"/g' /etc/init.d/dropbear - /etc/init.d/dropbear restart - mi_autoSSH_pwd=$(grep 'mi_autoSSH_pwd=' $CRASHDIR/configs/ShellCrash.cfg | awk -F "=" '{print $2}') - [ -n "$mi_autoSSH_pwd" ] && echo -e "$mi_autoSSH_pwd\n$mi_autoSSH_pwd" | passwd root - } - #配置nvram - [ "$(nvram get ssh_en)" = 0 ] && nvram set ssh_en=1 - [ "$(nvram get telnet_en)" = 0 ] && nvram set telnet_en=1 - nvram commit &> /dev/null - #备份还原SSH秘钥 - [ -f $CRASHDIR/configs/dropbear_rsa_host_key ] && ln -sf $CRASHDIR/configs/dropbear_rsa_host_key /etc/dropbear/dropbear_rsa_host_key - [ -f $CRASHDIR/configs/authorized_keys ] && ln -sf $CRASHDIR/configs/authorized_keys /etc/dropbear/authorized_keys -} -tunfix(){ - ko_dir=$(modinfo ip_tables | grep -Eo '/lib/modules.*/ip_tables.ko' | sed 's|/ip_tables.ko||' ) - #在/tmp创建并挂载overlay - mkdir -p /tmp/overlay - mkdir -p /tmp/overlay/upper - mkdir -p /tmp/overlay/work - mount -o noatime,lowerdir=${ko_dir},upperdir=/tmp/overlay/upper,workdir=/tmp/overlay/work -t overlay "overlay_mods_only" ${ko_dir} - #将tun.ko链接到lib - ln -sf $CRASHDIR/tools/tun.ko ${ko_dir}/tun.ko || $CRASHDIR/start.sh loggger "小米Tun模块修复失败!" -} -tproxyfix(){ - sed -i 's/sysctl -w net.bridge.bridge-nf-call-ip/#sysctl -w net.bridge.bridge-nf-call-ip/g' /etc/init.d/qca-nss-ecm - sysctl -w net.bridge.bridge-nf-call-iptables=0 - sysctl -w net.bridge.bridge-nf-call-ip6tables=0 -} -auto_clean(){ - #自动清理升级备份文件夹 - rm -rf /data/etc_bak - #自动清理被写入闪存的系统日志并禁止服务 - /etc/init.d/stat_points stop 2>/dev/null - /etc/init.d/stat_points disable 2>/dev/null - sed -i '\#/logrotate#{ /^[[:space:]]*#/!s/^/#ShellCrash自动注释 / }' /etc/crontabs/root - rm -rf /data/usr/log -} -init(){ - #等待启动完成 - while ! ip a| grep -q lan; do - sleep 10 - done - sleep 20 - #初始化环境变量 - [ -z "$my_alias" ] && my_alias=crash - sed -i "/ShellCrash\/menu.sh/"d "$profile" - echo "alias ${my_alias}=\"sh $CRASHDIR/menu.sh\"" >>"$profile" - sed -i "/export CRASHDIR/d" "$profile" - echo "export CRASHDIR=\"$CRASHDIR\"" >>"$profile" - autoSSH #软固化功能 - auto_clean #自动清理 - #设置init.d服务 - cp -f $CRASHDIR/shellcrash.procd /etc/init.d/shellcrash - chmod 755 /etc/init.d/shellcrash - #启动服务 - if [ ! -f $CRASHDIR/.dis_startup ]; then - #AX6S/AX6000修复tun功能 - [ -s $CRASHDIR/tools/tun.ko ] && tunfix - #小米7000/小米万兆修复tproxy - [ -f /etc/init.d/qca-nss-ecm ] && [ -n "$(grep 'redir_mod=Tproxy' $CRASHDIR/configs/ShellCrash.cfg )" ] && tproxyfix - #自动覆盖根证书文件 - [ -s $CRASHDIR/tools/ca-certificates.crt ] && cp -f $CRASHDIR/tools/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt - #启动服务 - $CRASHDIR/start.sh start - /etc/init.d/shellcrash enable - fi -} - -case "$1" in - tunfix) tunfix ;; - tproxyfix) tproxyfix ;; - auto_clean) auto_clean ;; - init) init ;; - *) - if [ -z $(pidof CrashCore) ];then - init & - fi - ;; -esac - diff --git a/scripts/starts/start_error.sh b/scripts/starts/start_error.sh new file mode 100644 index 00000000..e873661d --- /dev/null +++ b/scripts/starts/start_error.sh @@ -0,0 +1,12 @@ + +if [ "$start_old" != "已开启" ] && ckcmd journalctl; then + journalctl -u shellcrash >"$TMPDIR"/core_test.log +else + PID=$(pidof CrashCore) && [ -n "$PID" ] && kill -9 "$PID" >/dev/null 2>&1 + ${COMMAND} >"$TMPDIR"/core_test.log 2>&1 & + sleep 2 + kill $! >/dev/null 2>&1 +fi +error=$(cat $TMPDIR/core_test.log | grep -iEo 'error.*=.*|.*ERROR.*|.*FATAL.*') +logger "服务启动失败!请查看报错信息!详细信息请查看$TMPDIR/core_test.log" 33 +logger "$error" 31