diff --git a/install.sh b/install.sh index e70be35b..066a876d 100644 --- a/install.sh +++ b/install.sh @@ -11,271 +11,275 @@ echo "** by Juewuy **" echo "***********************************************" #内置工具 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}' + 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}' } ckcmd() { #检查命令 - command -v sh >/dev/null 2>&1 && command -v "$1" || type "$1" + command -v sh >/dev/null 2>&1 && command -v "$1" || type "$1" } webget() { - #参数【$1】代表下载目录,【$2】代表在线地址 - #参数【$3】代表输出显示,【$4】不启用重定向 - if curl --version >/dev/null 2>&1; then - [ "$3" = "echooff" ] && progress='-s' || progress='-#' - [ -z "$4" ] && redirect='-L' || redirect='' - result=$(curl -w %{http_code} --connect-timeout 5 $progress $redirect -ko $1 $2) - [ -n "$(echo $result | grep -e ^2)" ] && result="200" - else - if wget --version >/dev/null 2>&1; then - [ "$3" = "echooff" ] && progress='-q' || progress='-q --show-progress' - [ "$4" = "rediroff" ] && redirect='--max-redirect=0' || redirect='' - certificate='--no-check-certificate' - timeout='--timeout=3' - fi - [ "$3" = "echoon" ] && progress='' - [ "$3" = "echooff" ] && progress='-q' - wget $progress $redirect $certificate $timeout -O $1 $2 - [ $? -eq 0 ] && result="200" - fi + #参数【$1】代表下载目录,【$2】代表在线地址 + #参数【$3】代表输出显示,【$4】不启用重定向 + if curl --version >/dev/null 2>&1; then + [ "$3" = "echooff" ] && progress='-s' || progress='-#' + [ -z "$4" ] && redirect='-L' || redirect='' + result=$(curl -w %{http_code} --connect-timeout 5 $progress $redirect -ko $1 $2) + [ -n "$(echo $result | grep -e ^2)" ] && result="200" + else + if wget --version >/dev/null 2>&1; then + [ "$3" = "echooff" ] && progress='-q' || progress='-q --show-progress' + [ "$4" = "rediroff" ] && redirect='--max-redirect=0' || redirect='' + certificate='--no-check-certificate' + timeout='--timeout=3' + fi + [ "$3" = "echoon" ] && progress='' + [ "$3" = "echooff" ] && progress='-q' + wget $progress $redirect $certificate $timeout -O $1 $2 + [ $? -eq 0 ] && result="200" + fi } error_down() { - $echo "请参考 \033[32mhttps://github.com/juewuy/ShellCrash/blob/master/README_CN.md" - $echo "\033[33m使用其他安装源重新安装!\033[0m" + $echo "请参考 \033[32mhttps://github.com/juewuy/ShellCrash/blob/master/README_CN.md" + $echo "\033[33m使用其他安装源重新安装!\033[0m" } #安装及初始化 -set_alias(){ - echo ----------------------------------------------- - $echo "\033[36m请选择一个别名,或使用自定义别名:\033[0m" - echo ----------------------------------------------- - $echo " 1 【\033[32mcrash\033[0m】" - $echo " 2 【\033[32m sc \033[0m】" - $echo " 3 【\033[32m mm \033[0m】" - $echo " 0 退出安装" - echo ----------------------------------------------- - read -p "请输入相应数字或自定义别名 > " res - case "$res" in - 1) my_alias=crash ;; - 2) my_alias=sc ;; - 3) my_alias=mm ;; - *) my_alias=$res ;; - esac - cmd=$(ckcmd "$my_alias" | grep 'menu.sh') - ckcmd "$my_alias" >/dev/null 2>&1 && [ -z "$cmd" ] && { - $echo "\033[33m此别名和当前系统内置命令/别名冲突,请换一个!\033[0m" - sleep 1 - set_alias - } +set_alias() { + echo "-----------------------------------------------" + $echo "\033[36m请选择一个别名,或使用自定义别名:\033[0m" + echo "-----------------------------------------------" + $echo " 1 【\033[32mcrash\033[0m】" + $echo " 2 【\033[32m sc \033[0m】" + $echo " 3 【\033[32m mm \033[0m】" + $echo " 0 退出安装" + echo "-----------------------------------------------" + read -p "请输入相应数字或自定义别名 > " res + case "$res" in + 1) my_alias=crash ;; + 2) my_alias=sc ;; + 3) my_alias=mm ;; + *) my_alias=$res ;; + esac + cmd=$(ckcmd "$my_alias" | grep 'menu.sh') + ckcmd "$my_alias" >/dev/null 2>&1 && [ -z "$cmd" ] && { + $echo "\033[33m此别名和当前系统内置命令/别名冲突,请换一个!\033[0m" + sleep 1 + set_alias + } } gettar() { - webget /tmp/ShellCrash.tar.gz "$url/ShellCrash.tar.gz" - if [ "$result" != "200" ]; then - $echo "\033[33m文件下载失败!\033[0m" - error_down - exit 1 - else - $CRASHDIR/start.sh stop 2>/dev/null - #解压 - echo ----------------------------------------------- - echo 开始解压文件! - mkdir -p $CRASHDIR >/dev/null - tar -zxf '/tmp/ShellCrash.tar.gz' -C $CRASHDIR/ || tar -zxf '/tmp/ShellCrash.tar.gz' --no-same-owner -C $CRASHDIR/ - if [ -s $CRASHDIR/init.sh ]; then - set_alias - . $CRASHDIR/init.sh >/dev/null - [ "$?" != 0 ] && $echo "\033[33m初始化失败,请尝试本地安装!\033[0m" && exit 1 - else - rm -rf /tmp/ShellCrash.tar.gz - $echo "\033[33m文件解压失败!\033[0m" - error_down - exit 1 - fi - fi + webget /tmp/ShellCrash.tar.gz "$url/ShellCrash.tar.gz" + if [ "$result" != "200" ]; then + $echo "\033[33m文件下载失败!\033[0m" + error_down + exit 1 + else + $CRASHDIR/start.sh stop 2>/dev/null + #解压 + echo "-----------------------------------------------" + echo 开始解压文件! + mkdir -p $CRASHDIR >/dev/null + tar -zxf '/tmp/ShellCrash.tar.gz' -C $CRASHDIR/ || tar -zxf '/tmp/ShellCrash.tar.gz' --no-same-owner -C $CRASHDIR/ + if [ -s $CRASHDIR/init.sh ]; then + set_alias + . $CRASHDIR/init.sh >/dev/null + [ "$?" != 0 ] && $echo "\033[33m初始化失败,请尝试本地安装!\033[0m" && exit 1 + else + rm -rf /tmp/ShellCrash.tar.gz + $echo "\033[33m文件解压失败!\033[0m" + error_down + exit 1 + fi + fi } setdir() { - set_usb_dir() { - $echo "请选择安装目录" - 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 "\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 ----------------------------------------------- - $echo "\033[33m注意:安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m" - if [ -n "$systype" ]; then - [ "$systype" = "Padavan" ] && dir=/etc/storage - [ "$systype" = "mi_snapshot" ] && { - $echo "\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 "\033[33m检测到当前设备为华硕固件,请选择安装方式\033[0m" - $echo " 1 基于USB设备安装(限23年9月之前固件,须插入\033[31m任意\033[0mUSB设备)" - $echo " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)" - $echo " 3 基于U盘+下载大师安装(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" - $echo " 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 "如无法正常开机启动,请重新使用USB方式安装!" - sleep 2 - dir=/jffs - ;; - 3) - echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!" - sleep 2 - set_asus_dir - ;; - *) - exit 1 - ;; - esac - } - [ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt - else - $echo " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)" - $echo " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)" - $echo " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)" - $echo " 4 在\033[32m外置存储\033[0m中安装" - $echo " 5 手动设置安装目录" - $echo " 0 退出安装" - echo ----------------------------------------------- - read -p "请输入相应数字 > " num - #设置目录 - if [ -z $num ]; then - echo 安装已取消 - exit 1 - elif [ "$num" = "1" ]; then - dir=/etc - elif [ "$num" = "2" ]; then - dir=/usr/share - elif [ "$num" = "3" ]; then - dir=~/.local/share - mkdir -p ~/.config/systemd/user - elif [ "$num" = "4" ]; then - set_usb_dir - elif [ "$num" = "5" ]; then - set_cust_dir - else - echo 安装已取消!!! - exit 1 - fi - fi + set_usb_dir() { + $echo "请选择安装目录" + 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 "\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 "-----------------------------------------------" + $echo "\033[33m注意:安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m" + if [ -n "$systype" ]; then + [ "$systype" = "Padavan" ] && dir=/etc/storage + [ "$systype" = "mi_snapshot" ] && { + $echo "\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 "\033[33m检测到当前设备为华硕固件,请选择安装方式\033[0m" + $echo " 1 基于USB设备安装(限23年9月之前固件,须插入\033[31m任意\033[0mUSB设备)" + $echo " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)" + $echo " 3 基于U盘+下载大师安装(支持所有固件,限ARM设备,须插入U盘或移动硬盘)" + $echo " 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 "如无法正常开机启动,请重新使用USB方式安装!" + sleep 2 + dir=/jffs + ;; + 3) + echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!" + sleep 2 + set_asus_dir + ;; + *) + exit 1 + ;; + esac + } + [ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt + else + $echo " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)" + $echo " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)" + $echo " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)" + $echo " 4 在\033[32m外置存储\033[0m中安装" + $echo " 5 手动设置安装目录" + $echo " 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) + set_cust_dir + ;; + *) + echo "安装已取消" + exit 1 + ;; + esac + fi - if [ ! -w $dir ]; then - $echo "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir - else - $echo "目标目录\033[32m$dir\033[0m空间剩余:$(dir_avail $dir -h)" - read -p "确认安装?(1/0) > " res - [ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir - fi + if [ ! -w $dir ]; then + $echo "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir + else + $echo "目标目录\033[32m$dir\033[0m空间剩余:$(dir_avail $dir -h)" + read -p "确认安装?(1/0) > " res + [ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir + fi } install() { - echo ----------------------------------------------- - echo 开始从服务器获取安装文件! - echo ----------------------------------------------- - gettar - echo ----------------------------------------------- - echo ShellCrash 已经安装成功! - [ "$profile" = "~/.bashrc" ] && echo "请执行【. ~/.bashrc > /dev/null】命令以加载环境变量!" - [ -n "$(ls -l /bin/sh | grep -oE 'zsh')" ] && echo "请执行【. ~/.zshrc > /dev/null】命令以加载环境变量!" - echo ----------------------------------------------- - $echo "\033[33m输入\033[30;47m $my_alias \033[0;33m命令即可管理!!!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" + echo 开始从服务器获取安装文件! + echo "-----------------------------------------------" + gettar + echo "-----------------------------------------------" + echo "ShellCrash 已经安装成功!" + [ "$profile" = "~/.bashrc" ] && echo "请执行【. ~/.bashrc > /dev/null】命令以加载环境变量!" + [ -n "$(ls -l /bin/sh | grep -oE 'zsh')" ] && echo "请执行【. ~/.zshrc > /dev/null】命令以加载环境变量!" + echo "-----------------------------------------------" + $echo "\033[33m输入\033[30;47m $my_alias \033[0;33m命令即可管理!!!\033[0m" + echo "-----------------------------------------------" } setversion() { - echo ----------------------------------------------- - $echo "\033[33m请选择想要安装的版本:\033[0m" - $echo " 1 \033[32m公测版(推荐)\033[0m" - $echo " 2 \033[36m稳定版\033[0m" - $echo " 3 \033[31m开发版\033[0m" - echo ----------------------------------------------- - read -p "请输入相应数字 > " num - case "$num" in - 2) - url=$(echo $url | sed 's/master/stable/') - ;; - 3) - url=$(echo $url | sed 's/master/dev/') - ;; - *) ;; - esac + echo "-----------------------------------------------" + $echo "\033[33m请选择想要安装的版本:\033[0m" + $echo " 1 \033[32m公测版(推荐)\033[0m" + $echo " 2 \033[36m稳定版\033[0m" + $echo " 3 \033[31m开发版\033[0m" + echo "-----------------------------------------------" + read -p "请输入相应数字 > " num + case "$num" in + 2) + url=$(echo $url | sed 's/master/stable/') + ;; + 3) + url=$(echo $url | sed 's/master/dev/') + ;; + *) ;; + esac } #特殊固件识别及标记 [ -f "/etc/storage/started_script.sh" ] && { - systype=Padavan #老毛子固件 - initdir='/etc/storage/started_script.sh' + systype=Padavan #老毛子固件 + initdir='/etc/storage/started_script.sh' } [ -d "/jffs" ] && { - systype=asusrouter #华硕固件 - [ -f "/jffs/.asusrouter" ] && initdir='/jffs/.asusrouter' - [ -d "/jffs/scripts" ] && initdir='/jffs/scripts/nat-start' + systype=asusrouter #华硕固件 + [ -f "/jffs/.asusrouter" ] && initdir='/jffs/.asusrouter' + [ -d "/jffs/scripts" ] && initdir='/jffs/scripts/nat-start' } [ -f "/data/etc/crontabs/root" ] && systype=mi_snapshot #小米设备 [ -w "/var/mnt/cfg/firewall" ] && systype=ng_snapshot #NETGEAR设备 #检查root权限 if [ "$USER" != "root" -a -z "$systype" ]; then - echo 当前用户:$USER - $echo "\033[31m请尽量使用root用户(不要直接使用sudo命令!)执行安装!\033[0m" - echo ----------------------------------------------- - read -p "仍要安装?可能会产生未知错误!(1/0) > " res - [ "$res" != "1" ] && exit 1 + echo 当前用户:$USER + $echo "\033[31m请尽量使用root用户(不要直接使用sudo命令!)执行安装!\033[0m" + echo "-----------------------------------------------" + read -p "仍要安装?可能会产生未知错误!(1/0) > " res + [ "$res" != "1" ] && exit 1 fi if [ -n "$(echo $url | grep master)" ]; then - setversion + setversion fi #获取版本信息 webget /tmp/version "$url/version" echooff @@ -284,33 +288,38 @@ rm -rf /tmp/version #输出 $echo "最新版本:\033[32m$versionsh\033[0m" -echo ----------------------------------------------- +echo "-----------------------------------------------" $echo "\033[44m如遇问题请加TG群反馈:\033[42;30m t.me/ShellClash \033[0m" $echo "\033[37m支持各种基于openwrt的路由器设备" $echo "\033[33m支持Debian、Centos等标准Linux系统\033[0m" if [ -n "$CRASHDIR" ]; then - echo ----------------------------------------------- - $echo "检测到旧的安装目录\033[36m$CRASHDIR\033[0m,是否覆盖安装?" - $echo "\033[32m覆盖安装时不会移除配置文件!\033[0m" - read -p "覆盖安装/卸载旧版本?(1/0) > " res - if [ "$res" = "1" ]; then - install - elif [ "$res" = "0" ]; then - rm -rf $CRASHDIR - echo ----------------------------------------------- - $echo "\033[31m 旧版本文件已卸载!\033[0m" - setdir - install - elif [ "$res" = "9" ]; then - echo 测试模式,变更安装位置 - setdir - install - else - $echo "\033[31m输入错误!已取消安装!\033[0m" - exit 1 - fi + echo "-----------------------------------------------" + $echo "检测到旧的安装目录\033[36m$CRASHDIR\033[0m,是否覆盖安装?" + $echo "\033[32m覆盖安装时不会移除配置文件!\033[0m" + read -p "覆盖安装/卸载旧版本?(1/0) > " res + case "$res" in + 1) + install + ;; + 0) + rm -rf $CRASHDIR + echo "-----------------------------------------------" + $echo "\033[31m 旧版本文件已卸载!\033[0m" + setdir + install + ;; + 9) + echo "测试模式,变更安装位置" + setdir + install + ;; + *) + $echo "\033[31m输入错误!已取消安装!\033[0m" + exit 1 + ;; + esac else - setdir - install + setdir + install fi diff --git a/scripts/init.sh b/scripts/init.sh index 72d96985..1730b8e0 100644 --- a/scripts/init.sh +++ b/scripts/init.sh @@ -4,168 +4,172 @@ version=1.9.3beta7fix 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 - #设置目录 - if [ -z $num ]; then - echo 安装已取消 - exit 1 - elif [ "$num" = "1" ]; then - dir=/etc - elif [ "$num" = "2" ]; then - dir=/usr/share - elif [ "$num" = "3" ]; then - dir=~/.local/share - mkdir -p ~/.config/systemd/user - elif [ "$num" = "4" ]; then - set_usb_dir - elif [ "$num" = "5" ]; then - 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 - else - echo 安装已取消!!! - exit 1 - fi - fi + 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 + 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 + #参数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 #老毛子固件 - initdir='/etc/storage/started_script.sh' + systype=Padavan #老毛子固件 + initdir='/etc/storage/started_script.sh' } [ -d "/jffs" ] && { - systype=asusrouter #华硕固件 - [ -f "/jffs/.asusrouter" ] && initdir='/jffs/.asusrouter' - [ -d "/jffs/scripts" ] && initdir='/jffs/scripts/nat-start' - #华硕启用jffs - nvram set jffs2_scripts="1" - nvram commit + systype=asusrouter #华硕固件 + [ -f "/jffs/.asusrouter" ] && initdir='/jffs/.asusrouter' + [ -d "/jffs/scripts" ] && initdir='/jffs/scripts/nat-start' + #华硕启用jffs + nvram set jffs2_scripts="1" + nvram commit } [ -f "/data/etc/crontabs/root" ] && systype=mi_snapshot #小米设备 [ -w "/var/mnt/cfg/firewall" ] && systype=ng_snapshot #NETGEAR设备 @@ -184,62 +188,62 @@ mkdir -p ${CRASHDIR}/configs [ -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}/shellcrash.procd /etc/init.d/shellcrash - chmod 755 /etc/init.d/shellcrash - rm -rf ${CRASHDIR}/shellcrash.openrc + #设为init.d方式启动 + cp -f ${CRASHDIR}/shellcrash.procd /etc/init.d/shellcrash + chmod 755 /etc/init.d/shellcrash + rm -rf ${CRASHDIR}/shellcrash.openrc elif [ -n "$sysdir" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then - #创建shellcrash用户 - userdel shellcrash 2>/dev/null - sed -i '/0:7890/d' /etc/passwd - sed -i '/x:7890/d' /etc/group - if useradd -h >/dev/null 2>&1; then - useradd shellcrash -u 7890 2>/dev/null - sed -Ei s/7890:7890/0:7890/g /etc/passwd - else - echo "shellcrash:x:0:7890::/home/shellcrash:/bin/sh" >>/etc/passwd - fi - #配置systemd - mv -f ${CRASHDIR}/shellcrash.service $sysdir/shellcrash.service 2>/dev/null - sed -i "s%/etc/ShellCrash%$CRASHDIR%g" $sysdir/shellcrash.service - systemctl daemon-reload -elif rc-status -r >/dev/null 2>&1; then - #设为openrc方式启动 - cp -f ${CRASHDIR}/shellcrash.openrc /etc/init.d/shellcrash - chmod 755 /etc/init.d/shellcrash - rm -rf ${CRASHDIR}/shellcrash.procd + #创建shellcrash用户 + userdel shellcrash 2>/dev/null + sed -i '/0:7890/d' /etc/passwd + sed -i '/x:7890/d' /etc/group + if useradd -h >/dev/null 2>&1; then + useradd shellcrash -u 7890 2>/dev/null + sed -Ei s/7890:7890/0:7890/g /etc/passwd + else + echo "shellcrash:x:0:7890::/home/shellcrash:/bin/sh" >>/etc/passwd + fi + #配置systemd + mv -f ${CRASHDIR}/shellcrash.service $sysdir/shellcrash.service 2>/dev/null + sed -i "s%/etc/ShellCrash%$CRASHDIR%g" $sysdir/shellcrash.service + systemctl daemon-reload +elif rc-status -r >/dev/null 2>&1; then + #设为openrc方式启动 + cp -f ${CRASHDIR}/shellcrash.openrc /etc/init.d/shellcrash + chmod 755 /etc/init.d/shellcrash + rm -rf ${CRASHDIR}/shellcrash.procd else - #设为保守模式启动 - setconfig start_old 已开启 + #设为保守模式启动 + setconfig start_old 已开启 fi #修饰文件及版本号 command -v bash >/dev/null 2>&1 && shtype=bash [ -x /bin/ash ] && shtype=ash for file in start.sh task.sh menu.sh; do - sed -i "s|/bin/sh|/bin/$shtype|" ${CRASHDIR}/${file} 2>/dev/null - chmod 755 ${CRASHDIR}/${file} 2>/dev/null + sed -i "s|/bin/sh|/bin/$shtype|" ${CRASHDIR}/${file} 2>/dev/null + chmod 755 ${CRASHDIR}/${file} 2>/dev/null done setconfig versionsh_l $version #生成用于执行启动服务的变量文件 [ ! -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 + TMPDIR='/tmp/ShellCrash' + 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 - COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' + COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"' else - COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' + COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"' fi setconfig COMMAND "$COMMAND" ${CRASHDIR}/configs/command.env #设置防火墙执行模式 grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { - firewall_mod=iptables - nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables - setconfig firewall_mod $firewall_mod + firewall_mod=iptables + nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables + setconfig firewall_mod $firewall_mod } #设置更新地址 [ -n "$url" ] && setconfig update_url $url @@ -248,57 +252,57 @@ grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || { [ -w /jffs/configs/profile.add ] && profile=/jffs/configs/profile.add [ -w ~/.bashrc ] && profile=~/.bashrc [ -w /etc/profile ] && profile=/etc/profile -set_profile(){ - [ -z "$my_alias" ] && my_alias=crash - sed -i "/alias crash=*/"d "$1" - sed -i "/alias ${my_alias}=*/"d "$1" - echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量 - sed -i '/export CRASHDIR=*/'d "$1" - echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量 - . "$1" >/dev/null 2>&1 +set_profile() { + [ -z "$my_alias" ] && my_alias=crash + sed -i "/alias crash=*/"d "$1" + sed -i "/alias ${my_alias}=*/"d "$1" + echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量 + sed -i '/export CRASHDIR=*/'d "$1" + echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量 + . "$1" >/dev/null 2>&1 } if [ -n "$profile" ]; then - set_profile "$profile" - #适配zsh环境变量 - zsh --version >/dev/null 2>&1 && [ -z "$(cat ~/.zshrc 2>/dev/null | grep CRASHDIR)" ] && set_profile '~/.zshrc' 2>/dev/null - setconfig my_alias "$my_alias" + set_profile "$profile" + #适配zsh环境变量 + zsh --version >/dev/null 2>&1 && [ -z "$(cat ~/.zshrc 2>/dev/null | grep CRASHDIR)" ] && set_profile '~/.zshrc' 2>/dev/null + setconfig my_alias "$my_alias" else - echo -e "\033[33m无法写入环境变量!请检查安装权限!\033[0m" - exit 1 + echo -e "\033[33m无法写入环境变量!请检查安装权限!\033[0m" + exit 1 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 + sed -i '/ShellCrash初始化/'d $initdir + touch $initdir + echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >>$initdir + 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}/misnap_init.sh - uci delete firewall.ShellClash 2>/dev/null - uci delete firewall.ShellCrash 2>/dev/null - uci set firewall.ShellCrash=include - uci set firewall.ShellCrash.type='script' - uci set firewall.ShellCrash.path="$CRASHDIR/misnap_init.sh" - uci set firewall.ShellCrash.enabled='1' - uci commit firewall - setconfig systype $systype + chmod 755 ${CRASHDIR}/misnap_init.sh + uci delete firewall.ShellClash 2>/dev/null + uci delete firewall.ShellCrash 2>/dev/null + uci set firewall.ShellCrash=include + uci set firewall.ShellCrash.type='script' + uci set firewall.ShellCrash.path="$CRASHDIR/misnap_init.sh" + uci set firewall.ShellCrash.enabled='1' + uci commit firewall + setconfig systype $systype else - rm -rf ${CRASHDIR}/misnap_init.sh + rm -rf ${CRASHDIR}/misnap_init.sh fi #华硕USB启动额外设置 [ "$usb_status" = "1" ] && { - echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >${CRASHDIR}/asus_usb_mount.sh - nvram set script_usbmount="$CRASHDIR/asus_usb_mount.sh" - nvram commit + echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >${CRASHDIR}/asus_usb_mount.sh + nvram set script_usbmount="$CRASHDIR/asus_usb_mount.sh" + nvram commit } #华硕下载大师启动额外设置 [ -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ] && [ -z "$(grep 'ShellCrash' $dir/asusware.arm/etc/init.d/S50downloadmaster)" ] && - sed -i "/^PATH=/a\\$CRASHDIR/start.sh init & #ShellCrash初始化脚本" "$dir/asusware.arm/etc/init.d/S50downloadmaster" + sed -i "/^PATH=/a\\$CRASHDIR/start.sh init & #ShellCrash初始化脚本" "$dir/asusware.arm/etc/init.d/S50downloadmaster" #删除临时文件 rm -rf /tmp/*rash*gz rm -rf /tmp/SC_tmp @@ -309,11 +313,11 @@ 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 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}/mark ${CRASHDIR}/configs/ShellCrash.cfg 2>/dev/null @@ -330,10 +334,10 @@ mv -f ${CRASHDIR}/clash ${CRASHDIR}/CrashCore 2>/dev/null #内核压缩 [ -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.sh task.list; do - mv -f ${CRASHDIR}/$file ${CRASHDIR}/task/$file 2>/dev/null + mv -f ${CRASHDIR}/$file ${CRASHDIR}/task/$file 2>/dev/null done #旧版文件清理 userdel shellclash >/dev/null 2>&1 @@ -343,7 +347,7 @@ rm -rf /etc/init.d/clash 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 shellcrash.service mark? mark.bak; do - rm -rf ${CRASHDIR}/$file + rm -rf ${CRASHDIR}/$file done #旧版变量改名 sed -i "s/clashcore/crashcore/g" $configpath diff --git a/scripts/menu.sh b/scripts/menu.sh index 219b310a..4bb76ef0 100644 --- a/scripts/menu.sh +++ b/scripts/menu.sh @@ -2,8 +2,8 @@ # Copyright (C) Juewuy CRASHDIR=$( - cd $(dirname $0) - pwd + cd $(dirname $0) + pwd ) CFG_PATH=${CRASHDIR}/configs/ShellCrash.cfg YAMLSDIR=${CRASHDIR}/yamls @@ -16,2362 +16,2361 @@ JSONSDIR=${CRASHDIR}/jsons #读取配置相关 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 + #参数1代表变量名,参数2代表变量值,参数3即文件路径 + [ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}" + if grep -q "^${1}=" "$configpath"; then + sed -i "s#${1}=.*#${1}=${2}#g" "$configpath" + else + printf '%s=%s\n' "$1" "$2" >>"$configpath" + fi } ckcmd() { - command -v sh >/dev/null 2>&1 && command -v $1 >/dev/null 2>&1 || type $1 >/dev/null 2>&1 + command -v sh >/dev/null 2>&1 && command -v $1 >/dev/null 2>&1 || type $1 >/dev/null 2>&1 } #脚本启动前检查 ckstatus() { - #检查/读取脚本配置文件 - if [ -f $CFG_PATH ]; then - [ -n "$(awk 'a[$0]++' $CFG_PATH)" ] && awk '!a[$0]++' $CFG_PATH >$CFG_PATH #检查重复行并去除 - . $CFG_PATH 2>/dev/null - else - . ${CRASHDIR}/init.sh >/dev/null 2>&1 - fi - versionsh=$(cat ${CRASHDIR}/init.sh | grep -E ^version= | head -n 1 | sed 's/version=//') - [ -n "$versionsh" ] && versionsh_l=$versionsh - #服务器缺省地址 - [ -z "$mix_port" ] && mix_port=7890 - [ -z "$redir_port" ] && redir_port=7892 - [ -z "$fwmark" ] && fwmark=$redir_port - [ -z "$db_port" ] && db_port=9999 - [ -z "$dns_port" ] && dns_port=1053 - [ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' - [ -z "$redir_mod" ] && redir_mod=纯净模式 - #检查mac地址记录 - [ ! -f ${CRASHDIR}/configs/mac ] && touch ${CRASHDIR}/configs/mac - #获取本机host地址 - [ -z "$host" ] && host=$(ubus call network.interface.lan status 2>&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - [ -z "$host" ] && host=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'lan' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/\/[0-9][0-9].*$//g' | head -n 1) - [ -z "$host" ] && host=$(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) - [ -z "$host" ] && host='设备IP地址' - #dashboard目录位置 - if [ -f /www/clash/index.html ]; then - dbdir=/www/clash - hostdir=/clash - else - dbdir=${CRASHDIR}/ui - hostdir=":$db_port/ui" - fi - #开机自启检测 - if [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then - [ -n "$(find /etc/rc.d -name '*shellcrash')" ] && autostart=enable || autostart=disable - elif ckcmd systemctl; then - [ "$(systemctl is-enabled shellcrash.service 2>&1)" = enabled ] && autostart=enable || autostart=disable - elif rc-status -r >/dev/null 2>&1; then - rc-update show default | grep -q "shellcrash" && autostart=enable || autostart=disable - else - [ -f ${CRASHDIR}/.dis_startup ] && autostart=disable || autostart=enable - fi - #开机自启描述 - if [ "$autostart" = "enable" ]; then - auto="\033[32m已设置开机启动!\033[0m" - auto1="\033[36m禁用\033[0mShellCrash开机启动" - else - auto="\033[31m未设置开机启动!\033[0m" - auto1="\033[36m允许\033[0mShellCrash开机启动" - fi - #获取运行状态 - PID=$(pidof CrashCore | awk '{print $NF}') - if [ -n "$PID" ]; then - run="\033[32m正在运行($redir_mod)\033[0m" - VmRSS=$(cat /proc/$PID/status | grep -w VmRSS | awk 'unit="MB" {printf "%.2f %s\n", $2/1000, unit}') - #获取运行时长 - touch ${TMPDIR}/crash_start_time #用于延迟启动的校验 - start_time=$(cat ${TMPDIR}/crash_start_time) - if [ -n "$start_time" ]; then - time=$(($(date +%s) - start_time)) - day=$((time / 86400)) - [ "$day" = "0" ] && day='' || day="$day天" - time=$(date -u -d @${time} +%H小时%M分%S秒) - fi - elif [ "$firewall_area" = 5 ] && [ -n "$(ip route list table 100)" ]; then - run="\033[32m已设置($redir_mod)\033[0m" - else - run="\033[31m没有运行($redir_mod)\033[0m" - #检测系统端口占用 - checkport - fi - corename=$(echo $crashcore | sed 's/singboxr/SingBoxR/' | sed 's/singbox/SingBox/' | sed 's/clash/Clash/' | sed 's/meta/Mihomo/') - [ "$firewall_area" = 5 ] && corename='转发' - [ -f ${TMPDIR}/debug.log -o -f ${CRASHDIR}/debug.log -a -n "$PID" ] && auto="\033[33m并处于debug状态!\033[0m" - #输出状态 - echo ----------------------------------------------- - echo -e "\033[30;46m欢迎使用ShellCrash!\033[0m 版本:$versionsh_l" - echo -e "$corename服务"$run","$auto"" - if [ -n "$PID" ]; then - echo -e "当前内存占用:\033[44m"$VmRSS"\033[0m,已运行:\033[46;30m"$day"\033[44;37m"$time"\033[0m" - fi - echo -e "TG频道:\033[36;4mhttps://t.me/ShellClash\033[0m" - echo ----------------------------------------------- - #检查新手引导 - if [ -z "$userguide" ]; then - setconfig userguide 1 - . ${CRASHDIR}/webget.sh && userguide - fi - #检查执行权限 - [ ! -x ${CRASHDIR}/start.sh ] && chmod +x ${CRASHDIR}/start.sh - #检查/tmp内核文件 - for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(gz|zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do - chmod +x /tmp/$file - echo -e "发现可用的内核文件: \033[36m/tmp/$file\033[0m " - read -p "是否加载(会停止当前服务)?(1/0) > " res - [ "$res" = 1 ] && { - ${CRASHDIR}/start.sh stop - core_v=$(/tmp/$file -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') - [ -z "$core_v" ] && core_v=$(/tmp/$file version 2>/dev/null | grep -Eo 'version .*' | sed 's/version //') - if [ -n "$core_v" ]; then - . ${CRASHDIR}/webget.sh && setcoretype && - mv -f /tmp/$file ${TMPDIR}/CrashCore && - tar -zcf ${BINDIR}/CrashCore.tar.gz ${tar_para} -C ${TMPDIR} CrashCore && - echo -e "\033[32m内核加载完成!\033[0m " && - setconfig crashcore $crashcore && - setconfig core_v $core_v && - switch_core - sleep 1 - else - echo -e "\033[33m检测到不可用的内核文件!可能是文件受损或CPU架构不匹配!\033[0m" - rm -rf /tmp/$file - echo -e "\033[33m内核文件已移除,请认真检查后重新上传!\033[0m" - sleep 2 - fi - } - echo ----------------------------------------------- - done - #检查/tmp配置文件 - for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -iE '.yaml$|.yml$|config.json$'); do - tmp_file=/tmp/$file - echo -e "发现内核配置文件: \033[36m/tmp/$file\033[0m " - read -p "是否加载为$crashcore的配置文件?(1/0) > " res - [ "$res" = 1 ] && { - if [ -n "$(echo /tmp/$file | grep -iE '.json$')" ]; then - mv -f /tmp/$file ${CRASHDIR}/jsons/config.json - else - mv -f /tmp/$file ${CRASHDIR}/yamls/config.yaml - fi - echo -e "\033[32m配置文件加载完成!\033[0m " - sleep 1 - } - done - #检查禁用配置覆写 - [ "$disoverride" = "1" ] && { - echo -e "\033[33m你已经禁用了配置文件覆写功能,这会导致大量脚本功能无法使用!\033[0m " - read -p "是否取消禁用?(1/0) > " res - [ "$res" = 1 ] && unset disoverride && setconfig disoverride - echo ----------------------------------------------- - } + #检查/读取脚本配置文件 + if [ -f $CFG_PATH ]; then + [ -n "$(awk 'a[$0]++' $CFG_PATH)" ] && awk '!a[$0]++' $CFG_PATH >$CFG_PATH #检查重复行并去除 + . $CFG_PATH 2>/dev/null + else + . ${CRASHDIR}/init.sh >/dev/null 2>&1 + fi + versionsh=$(cat ${CRASHDIR}/init.sh | grep -E ^version= | head -n 1 | sed 's/version=//') + [ -n "$versionsh" ] && versionsh_l=$versionsh + #服务器缺省地址 + [ -z "$mix_port" ] && mix_port=7890 + [ -z "$redir_port" ] && redir_port=7892 + [ -z "$fwmark" ] && fwmark=$redir_port + [ -z "$db_port" ] && db_port=9999 + [ -z "$dns_port" ] && dns_port=1053 + [ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443' + [ -z "$redir_mod" ] && redir_mod=纯净模式 + #检查mac地址记录 + [ ! -f ${CRASHDIR}/configs/mac ] && touch ${CRASHDIR}/configs/mac + #获取本机host地址 + [ -z "$host" ] && host=$(ubus call network.interface.lan status 2>&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') + [ -z "$host" ] && host=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'lan' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/\/[0-9][0-9].*$//g' | head -n 1) + [ -z "$host" ] && host=$(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) + [ -z "$host" ] && host='设备IP地址' + #dashboard目录位置 + if [ -f /www/clash/index.html ]; then + dbdir=/www/clash + hostdir=/clash + else + dbdir=${CRASHDIR}/ui + hostdir=":$db_port/ui" + fi + #开机自启检测 + if [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then + [ -n "$(find /etc/rc.d -name '*shellcrash')" ] && autostart=enable || autostart=disable + elif ckcmd systemctl; then + [ "$(systemctl is-enabled shellcrash.service 2>&1)" = enabled ] && autostart=enable || autostart=disable + elif rc-status -r >/dev/null 2>&1; then + rc-update show default | grep -q "shellcrash" && autostart=enable || autostart=disable + else + [ -f ${CRASHDIR}/.dis_startup ] && autostart=disable || autostart=enable + fi + #开机自启描述 + if [ "$autostart" = "enable" ]; then + auto="\033[32m已设置开机启动!\033[0m" + auto1="\033[36m禁用\033[0mShellCrash开机启动" + else + auto="\033[31m未设置开机启动!\033[0m" + auto1="\033[36m允许\033[0mShellCrash开机启动" + fi + #获取运行状态 + PID=$(pidof CrashCore | awk '{print $NF}') + if [ -n "$PID" ]; then + run="\033[32m正在运行($redir_mod)\033[0m" + VmRSS=$(cat /proc/$PID/status | grep -w VmRSS | awk 'unit="MB" {printf "%.2f %s\n", $2/1000, unit}') + #获取运行时长 + touch ${TMPDIR}/crash_start_time #用于延迟启动的校验 + start_time=$(cat ${TMPDIR}/crash_start_time) + if [ -n "$start_time" ]; then + time=$(($(date +%s) - start_time)) + day=$((time / 86400)) + [ "$day" = "0" ] && day='' || day="$day天" + time=$(date -u -d @${time} +%H小时%M分%S秒) + fi + elif [ "$firewall_area" = 5 ] && [ -n "$(ip route list table 100)" ]; then + run="\033[32m已设置($redir_mod)\033[0m" + else + run="\033[31m没有运行($redir_mod)\033[0m" + #检测系统端口占用 + checkport + fi + corename=$(echo $crashcore | sed 's/singboxr/SingBoxR/' | sed 's/singbox/SingBox/' | sed 's/clash/Clash/' | sed 's/meta/Mihomo/') + [ "$firewall_area" = 5 ] && corename='转发' + [ -f ${TMPDIR}/debug.log -o -f ${CRASHDIR}/debug.log -a -n "$PID" ] && auto="\033[33m并处于debug状态!\033[0m" + #输出状态 + echo "-----------------------------------------------" + echo -e "\033[30;46m欢迎使用ShellCrash!\033[0m 版本:$versionsh_l" + echo -e "$corename服务"$run","$auto"" + if [ -n "$PID" ]; then + echo -e "当前内存占用:\033[44m"$VmRSS"\033[0m,已运行:\033[46;30m"$day"\033[44;37m"$time"\033[0m" + fi + echo -e "TG频道:\033[36;4mhttps://t.me/ShellClash\033[0m" + echo "-----------------------------------------------" + #检查新手引导 + if [ -z "$userguide" ]; then + setconfig userguide 1 + . ${CRASHDIR}/webget.sh && userguide + fi + #检查执行权限 + [ ! -x ${CRASHDIR}/start.sh ] && chmod +x ${CRASHDIR}/start.sh + #检查/tmp内核文件 + for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(gz|zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do + chmod +x /tmp/$file + echo -e "发现可用的内核文件: \033[36m/tmp/$file\033[0m " + read -p "是否加载(会停止当前服务)?(1/0) > " res + [ "$res" = 1 ] && { + ${CRASHDIR}/start.sh stop + core_v=$(/tmp/$file -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //') + [ -z "$core_v" ] && core_v=$(/tmp/$file version 2>/dev/null | grep -Eo 'version .*' | sed 's/version //') + if [ -n "$core_v" ]; then + . ${CRASHDIR}/webget.sh && setcoretype && + mv -f /tmp/$file ${TMPDIR}/CrashCore && + tar -zcf ${BINDIR}/CrashCore.tar.gz ${tar_para} -C ${TMPDIR} CrashCore && + echo -e "\033[32m内核加载完成!\033[0m " && + setconfig crashcore $crashcore && + setconfig core_v $core_v && + switch_core + sleep 1 + else + echo -e "\033[33m检测到不可用的内核文件!可能是文件受损或CPU架构不匹配!\033[0m" + rm -rf /tmp/$file + echo -e "\033[33m内核文件已移除,请认真检查后重新上传!\033[0m" + sleep 2 + fi + } + echo "-----------------------------------------------" + done + #检查/tmp配置文件 + for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -iE '.yaml$|.yml$|config.json$'); do + tmp_file=/tmp/$file + echo -e "发现内核配置文件: \033[36m/tmp/$file\033[0m " + read -p "是否加载为$crashcore的配置文件?(1/0) > " res + [ "$res" = 1 ] && { + if [ -n "$(echo /tmp/$file | grep -iE '.json$')" ]; then + mv -f /tmp/$file ${CRASHDIR}/jsons/config.json + else + mv -f /tmp/$file ${CRASHDIR}/yamls/config.yaml + fi + echo -e "\033[32m配置文件加载完成!\033[0m " + sleep 1 + } + done + #检查禁用配置覆写 + [ "$disoverride" = "1" ] && { + echo -e "\033[33m你已经禁用了配置文件覆写功能,这会导致大量脚本功能无法使用!\033[0m " + read -p "是否取消禁用?(1/0) > " res + [ "$res" = 1 ] && unset disoverride && setconfig disoverride + echo "-----------------------------------------------" + } } errornum() { - echo ----------------------------------------------- - echo -e "\033[31m请输入正确的字母或数字!\033[0m" + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的字母或数字!\033[0m" } startover() { - echo -ne " \r" - echo -e "\033[32m服务已启动!\033[0m" - echo -e "请使用 \033[4;36mhttp://$host$hostdir\033[0m 管理内置规则" - if [ "$redir_mod" = "纯净模式" ]; then - echo ----------------------------------------------- - echo -e "其他设备可以使用PAC配置连接:\033[4;32mhttp://$host:$db_port/ui/pac\033[0m" - echo -e "或者使用HTTP/SOCK5方式连接:IP{\033[36m$host\033[0m}端口{\033[36m$mix_port\033[0m}" - fi - return 0 + echo -ne " \r" + echo -e "\033[32m服务已启动!\033[0m" + echo -e "请使用 \033[4;36mhttp://$host$hostdir\033[0m 管理内置规则" + if [ "$redir_mod" = "纯净模式" ]; then + echo "-----------------------------------------------" + echo -e "其他设备可以使用PAC配置连接:\033[4;32mhttp://$host:$db_port/ui/pac\033[0m" + echo -e "或者使用HTTP/SOCK5方式连接:IP{\033[36m$host\033[0m}端口{\033[36m$mix_port\033[0m}" + fi + return 0 } start_core() { - if echo "$crashcore" | grep -q 'singbox'; then - core_config=${CRASHDIR}/jsons/config.json - else - core_config=${CRASHDIR}/yamls/config.yaml - fi - echo ----------------------------------------------- - if [ ! -s $core_config -a -s $CRASHDIR/configs/providers.cfg ]; then - echo -e "\033[33m没有找到${crashcore}配置文件,尝试生成providers配置文件!\033[0m" - [ "$crashcore" = singboxr ] && coretype=singbox - [ "$crashcore" = meta -o "$crashcore" = clashpre ] && coretype=clash - . ${CRASHDIR}/webget.sh && gen_${coretype}_providers - 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 - [ -n "$test" -o -n "$(pidof CrashCore)" ] && startover - else - echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m" - . ${CRASHDIR}/webget.sh && set_core_config - fi + if echo "$crashcore" | grep -q 'singbox'; then + core_config=${CRASHDIR}/jsons/config.json + else + core_config=${CRASHDIR}/yamls/config.yaml + fi + echo "-----------------------------------------------" + if [ ! -s $core_config -a -s $CRASHDIR/configs/providers.cfg ]; then + echo -e "\033[33m没有找到${crashcore}配置文件,尝试生成providers配置文件!\033[0m" + [ "$crashcore" = singboxr ] && coretype=singbox + [ "$crashcore" = meta -o "$crashcore" = clashpre ] && coretype=clash + . ${CRASHDIR}/webget.sh && gen_${coretype}_providers + 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 + [ -n "$test" -o -n "$(pidof CrashCore)" ] && startover + else + echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m" + . ${CRASHDIR}/webget.sh && set_core_config + fi } start_service() { - if [ "$firewall_area" = 5 ]; then - ${CRASHDIR}/start.sh start - echo -e "\033[32m已完成防火墙设置!\033[0m" - else - start_core - fi + if [ "$firewall_area" = 5 ]; then + ${CRASHDIR}/start.sh start + echo -e "\033[32m已完成防火墙设置!\033[0m" + else + start_core + fi } checkrestart() { - echo ----------------------------------------------- - echo -e "\033[32m检测到已变更的内容,请重启服务!\033[0m" - echo ----------------------------------------------- - read -p "是否现在重启服务?(1/0) > " res - [ "$res" = 1 ] && start_service + echo "-----------------------------------------------" + echo -e "\033[32m检测到已变更的内容,请重启服务!\033[0m" + echo "-----------------------------------------------" + read -p "是否现在重启服务?(1/0) > " res + [ "$res" = 1 ] && start_service } #功能相关 log_pusher() { #日志菜单 - [ -n "$push_TG" ] && stat_TG=32m已启用 || stat_TG=33m未启用 - [ -n "$push_Deer" ] && stat_Deer=32m已启用 || stat_Deer=33m未启用 - [ -n "$push_bark" ] && stat_bark=32m已启用 || stat_bark=33m未启用 - [ -n "$push_Po" ] && stat_Po=32m已启用 || stat_Po=33m未启用 - [ -n "$push_PP" ] && stat_PP=32m已启用 || stat_PP=33m未启用 - [ -n "$push_SynoChat" ] && stat_SynoChat=32m已启用 || stat_SynoChat=33m未启用 - [ -n "$push_Gotify" ] && stat_Gotify=32m已启用 || stat_Gotify=33m未启用 - [ "$task_push" = 1 ] && stat_task=32m已启用 || stat_task=33m未启用 - [ -n "$device_name" ] && device_s=32m$device_name || device_s=33m未设置 - echo ----------------------------------------------- - echo -e " 1 Telegram推送 ——\033[$stat_TG\033[0m" - echo -e " 2 PushDeer推送 ——\033[$stat_Deer\033[0m" - echo -e " 3 Bark推送-IOS ——\033[$stat_bark\033[0m" - echo -e " 4 Passover推送 ——\033[$stat_Po\033[0m" - echo -e " 5 PushPlus推送 ——\033[$stat_PP\033[0m" - echo -e " 6 SynoChat推送 ——\033[$stat_SynoChat\033[0m" - echo -e " 7 Gotify推送 ——\033[$stat_Gotify\033[0m" - echo ----------------------------------------------- - echo -e " a 查看\033[36m运行日志\033[0m" - echo -e " b 推送任务日志 ——\033[$stat_task\033[0m" - echo -e " c 设置设备名称 ——\033[$device_s\033[0m" - echo -e " d 清空日志文件" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - a) - if [ -s ${TMPDIR}/ShellCrash.log ]; then - echo ----------------------------------------------- - cat ${TMPDIR}/ShellCrash.log - exit 0 - else - echo -e "\033[31m未找到相关日志!\033[0m" - fi - sleep 1 - ;; - 1) - echo ----------------------------------------------- - if [ -n "$push_TG" ]; then - read -p "确认关闭TG日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_TG= - chat_ID= - setconfig push_TG - setconfig chat_ID - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - private_bot(){ - echo -e "请先通过 \033[32;4mhttps://t.me/BotFather\033[0m 申请TG机器人并获取其\033[36mAPI TOKEN\033[0m" - echo ----------------------------------------------- - read -p "请输入你获取到的API TOKEN > " TOKEN - echo ----------------------------------------------- - echo -e "请向\033[32m你申请的机器人\033[33m而不是BotFather!\033[0m" - url_tg=https://api.telegram.org/bot${TOKEN}/getUpdates - } - public_bot(){ - echo -e "请向机器人:\033[32;4mhttps://t.me/ShellCrashtg_bot\033[0m" - TOKEN=publictoken - url_tg=https://tgbot.jwsc.eu.org/publictoken/getUpdates - } - set_bot(){ - echo -e "发送此秘钥: \033[30;46m$public_key\033[0m" - echo ----------------------------------------------- - read -p "我已经发送完成(1/0) > " res - if [ "$res" = 1 ]; then - [ -n "$authentication" ] && auth="$authentication@" - export https_proxy="http://${auth}127.0.0.1:$mix_port" - if curl --version >/dev/null 2>&1; then - chat=$(curl -kfsSl $url_tg 2>/dev/null) - else - chat=$(wget -Y on -q -O - $url_tg) - fi - [ -n "$chat" ] && chat_ID=$(echo $chat | sed 's/"update_id":/{\n"update_id":/g' | grep "$public_key" | head -n1 |grep -oE '"id":.*,"is_bot' | sed s'/"id"://' | sed s'/,"is_bot//') - [ -z "$chat_ID" ] && { - echo -e "\033[31m无法获取对话ID,请返回重新设置或手动输入ChatID!\033[0m" - echo -e "通常访问 \033[32;4m$url_tg\033[0m \n\033[36m即可看到ChatID\033[0m" - read -p "请手动输入ChatID > " chat_ID - } - if echo "$chat_ID" | grep -qE '^[0-9]{8,}$'; then - push_TG=$TOKEN - setconfig push_TG $TOKEN - setconfig chat_ID $chat_ID - ${CRASHDIR}/start.sh logger "已完成Telegram日志推送设置!" 32 - else - echo -e "\033[31m无法获取对话ID,请重新配置!\033[0m" - sleep 1 - chose_bot - fi - fi - } - chose_bot(){ - public_key=$(cat /proc/sys/kernel/random/boot_id | sed 's/.*-//') - echo ----------------------------------------------- - echo -e " 1 使用公共机器人 ——不依赖内核服务" - echo -e " 2 使用私人机器人 ——需要额外申请" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - 1) - public_bot - set_bot - ;; - 2) - private_bot - set_bot - ;; - *) - errornum - ;; - esac - } - chose_bot - fi - sleep 1 - log_pusher - ;; - 2) - echo ----------------------------------------------- - if [ -n "$push_Deer" ]; then - read -p "确认关闭PushDeer日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Deer= - setconfig push_Deer - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先前往 \033[32;4mhttp://www.pushdeer.com/official.html\033[0m 扫码安装快应用或下载APP" - echo -e "打开快应用/APP,并完成登陆" - echo -e "\033[33m切换到「设备」标签页,点击右上角的加号,注册当前设备\033[0m" - echo -e "\033[36m切换到「秘钥」标签页,点击右上角的加号,创建一个秘钥,并复制\033[0m" - echo ----------------------------------------------- - read -p "请输入你复制的秘钥 > " url - if [ -n "$url" ]; then - push_Deer=$url - setconfig push_Deer $url - ${CRASHDIR}/start.sh logger "已完成PushDeer日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - sleep 1 - fi - log_pusher - ;; - 3) - echo ----------------------------------------------- - if [ -n "$push_bark" ]; then - read -p "确认关闭Bark日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_bark= - bark_param= - setconfig push_bark - setconfig bark_param - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "\033[33mBark推送仅支持IOS系统,其他平台请使用其他推送方式!\033[0m" - echo -e "\033[32m请安装Bark-IOS客户端,并在客户端中找到专属推送链接\033[0m" - echo ----------------------------------------------- - read -p "请输入你的Bark推送链接 > " url - if [ -n "$url" ]; then - push_bark=$url - setconfig push_bark $url - ${CRASHDIR}/start.sh logger "已完成Bark日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - sleep 1 - fi - log_pusher - ;; - 4) - echo ----------------------------------------------- - if [ -n "$push_Po" ]; then - read -p "确认关闭Pushover日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Po= - push_Po_key= - setconfig push_Po - setconfig push_Po_key - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先通过 \033[32;4mhttps://pushover.net/\033[0m 注册账号并获取\033[36mUser Key\033[0m" - echo ----------------------------------------------- - read -p "请输入你的User Key > " key - if [ -n "$key" ]; then - echo ----------------------------------------------- - echo -e "\033[33m请检查注册邮箱,完成账户验证\033[0m" - read -p "我已经验证完成(1/0) > " - echo ----------------------------------------------- - echo -e "请通过 \033[32;4mhttps://pushover.net/apps/build\033[0m 生成\033[36mAPI Token\033[0m" - echo ----------------------------------------------- - read -p "请输入你的API Token > " Token - if [ -n "$Token" ]; then - push_Po=$Token - push_Po_key=$key - setconfig push_Po $Token - setconfig push_Po_key $key - ${CRASHDIR}/start.sh logger "已完成Passover日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - 5) - echo ----------------------------------------------- - if [ -n "$push_PP" ]; then - read -p "确认关闭PushPlus日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_PP= - setconfig push_PP - } - else - #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" - echo -e "请先通过 \033[32;4mhttps://www.pushplus.plus/push1.html\033[0m 注册账号并获取\033[36mtoken\033[0m" - echo ----------------------------------------------- - read -p "请输入你的token > " Token - if [ -n "$Token" ]; then - push_PP=$Token - setconfig push_PP $Token - ${CRASHDIR}/start.sh logger "已完成PushPlus日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - 6) - echo ----------------------------------------------- - if [ -n "$push_SynoChat" ]; then - read -p "确认关闭SynoChat日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_SynoChat= - setconfig push_SynoChat - } - else - echo ----------------------------------------------- - read -p "请输入你的Synology DSM主页地址 > " URL - echo ----------------------------------------------- - read -p "请输入你的Synology Chat Token > " TOKEN - echo ----------------------------------------------- - echo -e '请通过"你的群晖地址/webapi/entry.cgi?api=SYNO.Chat.External&method=user_list&version=2&token=你的TOKEN"获取user_id' - echo ----------------------------------------------- - read -p "请输入你的user_id > " USERID - if [ -n "$URL" ]; then - push_SynoChat=$USERID - setconfig push_SynoChat $USERID - setconfig push_ChatURL $URL - setconfig push_ChatTOKEN $TOKEN - setconfig push_ChatUSERID $USERID - ${CRASHDIR}/start.sh logger "已完成SynoChat日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - setconfig push_ChatURL - setconfig push_ChatTOKEN - setconfig push_ChatUSERID - push_SynoChat= - setconfig push_SynoChat - fi - fi - sleep 1 - log_pusher - ;; - # 在menu.sh的case $num in代码块中添加 - 7) - echo ----------------------------------------------- - if [ -n "$push_Gotify" ]; then - read -p "确认关闭Gotify日志推送?(1/0) > " res - [ "$res" = 1 ] && { - push_Gotify= - setconfig push_Gotify - } - else - echo -e "请先通过Gotify服务器获取推送URL" - echo -e "格式示例: https://gotify.example.com/message?token=你的应用令牌" - echo ----------------------------------------------- - read -p "请输入你的Gotify推送URL > " url - if [ -n "$url" ]; then - push_Gotify=$url - setconfig push_Gotify "$url" - ${CRASHDIR}/start.sh logger "已完成Gotify日志推送设置!" 32 - else - echo -e "\033[31m输入错误,请重新输入!\033[0m" - fi - fi - sleep 1 - log_pusher - ;; - b) - [ "$task_push" = 1 ] && task_push='' || task_push=1 - setconfig task_push $task_push - sleep 1 - log_pusher - ;; - c) - read -p "请输入本设备自定义推送名称 > " device_name - setconfig device_name $device_name - sleep 1 - log_pusher - ;; - d) - echo -e "\033[33m运行日志及任务日志均已清空!\033[0m" - rm -rf ${TMPDIR}/ShellCrash.log - sleep 1 - log_pusher - ;; - *) errornum ;; - esac + [ -n "$push_TG" ] && stat_TG=32m已启用 || stat_TG=33m未启用 + [ -n "$push_Deer" ] && stat_Deer=32m已启用 || stat_Deer=33m未启用 + [ -n "$push_bark" ] && stat_bark=32m已启用 || stat_bark=33m未启用 + [ -n "$push_Po" ] && stat_Po=32m已启用 || stat_Po=33m未启用 + [ -n "$push_PP" ] && stat_PP=32m已启用 || stat_PP=33m未启用 + [ -n "$push_SynoChat" ] && stat_SynoChat=32m已启用 || stat_SynoChat=33m未启用 + [ -n "$push_Gotify" ] && stat_Gotify=32m已启用 || stat_Gotify=33m未启用 + [ "$task_push" = 1 ] && stat_task=32m已启用 || stat_task=33m未启用 + [ -n "$device_name" ] && device_s=32m$device_name || device_s=33m未设置 + echo "-----------------------------------------------" + echo -e " 1 Telegram推送 ——\033[$stat_TG\033[0m" + echo -e " 2 PushDeer推送 ——\033[$stat_Deer\033[0m" + echo -e " 3 Bark推送-IOS ——\033[$stat_bark\033[0m" + echo -e " 4 Passover推送 ——\033[$stat_Po\033[0m" + echo -e " 5 PushPlus推送 ——\033[$stat_PP\033[0m" + echo -e " 6 SynoChat推送 ——\033[$stat_SynoChat\033[0m" + echo -e " 7 Gotify推送 ——\033[$stat_Gotify\033[0m" + echo "-----------------------------------------------" + echo -e " a 查看\033[36m运行日志\033[0m" + echo -e " b 推送任务日志 ——\033[$stat_task\033[0m" + echo -e " c 设置设备名称 ——\033[$device_s\033[0m" + echo -e " d 清空日志文件" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + a) + if [ -s ${TMPDIR}/ShellCrash.log ]; then + echo "-----------------------------------------------" + cat ${TMPDIR}/ShellCrash.log + exit 0 + else + echo -e "\033[31m未找到相关日志!\033[0m" + fi + sleep 1 + ;; + 1) + echo "-----------------------------------------------" + if [ -n "$push_TG" ]; then + read -p "确认关闭TG日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_TG= + chat_ID= + setconfig push_TG + setconfig chat_ID + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + private_bot() { + echo -e "请先通过 \033[32;4mhttps://t.me/BotFather\033[0m 申请TG机器人并获取其\033[36mAPI TOKEN\033[0m" + echo "-----------------------------------------------" + read -p "请输入你获取到的API TOKEN > " TOKEN + echo "-----------------------------------------------" + echo -e "请向\033[32m你申请的机器人\033[33m而不是BotFather!\033[0m" + url_tg=https://api.telegram.org/bot${TOKEN}/getUpdates + } + public_bot() { + echo -e "请向机器人:\033[32;4mhttps://t.me/ShellCrashtg_bot\033[0m" + TOKEN=publictoken + url_tg=https://tgbot.jwsc.eu.org/publictoken/getUpdates + } + set_bot() { + echo -e "发送此秘钥: \033[30;46m$public_key\033[0m" + echo "-----------------------------------------------" + read -p "我已经发送完成(1/0) > " res + if [ "$res" = 1 ]; then + [ -n "$authentication" ] && auth="$authentication@" + export https_proxy="http://${auth}127.0.0.1:$mix_port" + if curl --version >/dev/null 2>&1; then + chat=$(curl -kfsSl $url_tg 2>/dev/null) + else + chat=$(wget -Y on -q -O - $url_tg) + fi + [ -n "$chat" ] && chat_ID=$(echo $chat | sed 's/"update_id":/{\n"update_id":/g' | grep "$public_key" | head -n1 | grep -oE '"id":.*,"is_bot' | sed s'/"id"://' | sed s'/,"is_bot//') + [ -z "$chat_ID" ] && { + echo -e "\033[31m无法获取对话ID,请返回重新设置或手动输入ChatID!\033[0m" + echo -e "通常访问 \033[32;4m$url_tg\033[0m \n\033[36m即可看到ChatID\033[0m" + read -p "请手动输入ChatID > " chat_ID + } + if echo "$chat_ID" | grep -qE '^[0-9]{8,}$'; then + push_TG=$TOKEN + setconfig push_TG $TOKEN + setconfig chat_ID $chat_ID + ${CRASHDIR}/start.sh logger "已完成Telegram日志推送设置!" 32 + else + echo -e "\033[31m无法获取对话ID,请重新配置!\033[0m" + sleep 1 + chose_bot + fi + fi + } + chose_bot() { + public_key=$(cat /proc/sys/kernel/random/boot_id | sed 's/.*-//') + echo "-----------------------------------------------" + echo -e " 1 使用公共机器人 ——不依赖内核服务" + echo -e " 2 使用私人机器人 ——需要额外申请" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case $num in + 1) + public_bot + set_bot + ;; + 2) + private_bot + set_bot + ;; + *) + errornum + ;; + esac + } + chose_bot + fi + sleep 1 + log_pusher + ;; + 2) + echo "-----------------------------------------------" + if [ -n "$push_Deer" ]; then + read -p "确认关闭PushDeer日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Deer= + setconfig push_Deer + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先前往 \033[32;4mhttp://www.pushdeer.com/official.html\033[0m 扫码安装快应用或下载APP" + echo -e "打开快应用/APP,并完成登陆" + echo -e "\033[33m切换到「设备」标签页,点击右上角的加号,注册当前设备\033[0m" + echo -e "\033[36m切换到「秘钥」标签页,点击右上角的加号,创建一个秘钥,并复制\033[0m" + echo "-----------------------------------------------" + read -p "请输入你复制的秘钥 > " url + if [ -n "$url" ]; then + push_Deer=$url + setconfig push_Deer $url + ${CRASHDIR}/start.sh logger "已完成PushDeer日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + sleep 1 + fi + log_pusher + ;; + 3) + echo "-----------------------------------------------" + if [ -n "$push_bark" ]; then + read -p "确认关闭Bark日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_bark= + bark_param= + setconfig push_bark + setconfig bark_param + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "\033[33mBark推送仅支持IOS系统,其他平台请使用其他推送方式!\033[0m" + echo -e "\033[32m请安装Bark-IOS客户端,并在客户端中找到专属推送链接\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的Bark推送链接 > " url + if [ -n "$url" ]; then + push_bark=$url + setconfig push_bark $url + ${CRASHDIR}/start.sh logger "已完成Bark日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + sleep 1 + fi + log_pusher + ;; + 4) + echo "-----------------------------------------------" + if [ -n "$push_Po" ]; then + read -p "确认关闭Pushover日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Po= + push_Po_key= + setconfig push_Po + setconfig push_Po_key + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先通过 \033[32;4mhttps://pushover.net/\033[0m 注册账号并获取\033[36mUser Key\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的User Key > " key + if [ -n "$key" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m请检查注册邮箱,完成账户验证\033[0m" + read -p "我已经验证完成(1/0) > " + echo "-----------------------------------------------" + echo -e "请通过 \033[32;4mhttps://pushover.net/apps/build\033[0m 生成\033[36mAPI Token\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的API Token > " Token + if [ -n "$Token" ]; then + push_Po=$Token + push_Po_key=$key + setconfig push_Po $Token + setconfig push_Po_key $key + ${CRASHDIR}/start.sh logger "已完成Passover日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + 5) + echo "-----------------------------------------------" + if [ -n "$push_PP" ]; then + read -p "确认关闭PushPlus日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_PP= + setconfig push_PP + } + else + #echo -e "\033[33m详细设置指南请参考 https://juewuy.github.io/ \033[0m" + echo -e "请先通过 \033[32;4mhttps://www.pushplus.plus/push1.html\033[0m 注册账号并获取\033[36mtoken\033[0m" + echo "-----------------------------------------------" + read -p "请输入你的token > " Token + if [ -n "$Token" ]; then + push_PP=$Token + setconfig push_PP $Token + ${CRASHDIR}/start.sh logger "已完成PushPlus日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + 6) + echo "-----------------------------------------------" + if [ -n "$push_SynoChat" ]; then + read -p "确认关闭SynoChat日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_SynoChat= + setconfig push_SynoChat + } + else + echo "-----------------------------------------------" + read -p "请输入你的Synology DSM主页地址 > " URL + echo "-----------------------------------------------" + read -p "请输入你的Synology Chat Token > " TOKEN + echo "-----------------------------------------------" + echo -e '请通过"你的群晖地址/webapi/entry.cgi?api=SYNO.Chat.External&method=user_list&version=2&token=你的TOKEN"获取user_id' + echo "-----------------------------------------------" + read -p "请输入你的user_id > " USERID + if [ -n "$URL" ]; then + push_SynoChat=$USERID + setconfig push_SynoChat $USERID + setconfig push_ChatURL $URL + setconfig push_ChatTOKEN $TOKEN + setconfig push_ChatUSERID $USERID + ${CRASHDIR}/start.sh logger "已完成SynoChat日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + setconfig push_ChatURL + setconfig push_ChatTOKEN + setconfig push_ChatUSERID + push_SynoChat= + setconfig push_SynoChat + fi + fi + sleep 1 + log_pusher + ;; + # 在menu.sh的case $num in代码块中添加 + 7) + echo "-----------------------------------------------" + if [ -n "$push_Gotify" ]; then + read -p "确认关闭Gotify日志推送?(1/0) > " res + [ "$res" = 1 ] && { + push_Gotify= + setconfig push_Gotify + } + else + echo -e "请先通过Gotify服务器获取推送URL" + echo -e "格式示例: https://gotify.example.com/message?token=你的应用令牌" + echo "-----------------------------------------------" + read -p "请输入你的Gotify推送URL > " url + if [ -n "$url" ]; then + push_Gotify=$url + setconfig push_Gotify "$url" + ${CRASHDIR}/start.sh logger "已完成Gotify日志推送设置!" 32 + else + echo -e "\033[31m输入错误,请重新输入!\033[0m" + fi + fi + sleep 1 + log_pusher + ;; + b) + [ "$task_push" = 1 ] && task_push='' || task_push=1 + setconfig task_push $task_push + sleep 1 + log_pusher + ;; + c) + read -p "请输入本设备自定义推送名称 > " device_name + setconfig device_name $device_name + sleep 1 + log_pusher + ;; + d) + echo -e "\033[33m运行日志及任务日志均已清空!\033[0m" + rm -rf ${TMPDIR}/ShellCrash.log + sleep 1 + log_pusher + ;; + *) errornum ;; + esac } setport() { #端口设置 - . $CFG_PATH >/dev/null - [ -z "$secret" ] && secret=未设置 - [ -z "$table" ] && table=100 - [ -z "$authentication" ] && auth=未设置 || auth=****** - inputport() { - read -p "请输入端口号(1-65535) > " portx - if [ -z "$portx" ]; then - setport - elif [ $portx -gt 65535 -o $portx -le 1 ]; then - echo -e "\033[31m输入错误!请输入正确的数值(1-65535)!\033[0m" - inputport - elif [ -n "$(echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep "|$portx|")" ]; then - echo -e "\033[31m输入错误!请不要输入重复的端口!\033[0m" - inputport - elif [ -n "$(netstat -ntul | grep ":$portx ")" ]; then - echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" - inputport - else - setconfig $xport $portx - echo -e "\033[32m设置成功!!!\033[0m" - setport - fi - } - echo ----------------------------------------------- - echo -e " 1 修改Http/Sock5端口: \033[36m$mix_port\033[0m" - echo -e " 2 设置Http/Sock5密码: \033[36m$auth\033[0m" - echo -e " 3 修改Redir/Tproxy端口:\033[36m$redir_port,$((redir_port + 1))\033[0m" - echo -e " 4 修改DNS监听端口: \033[36m$dns_port\033[0m" - echo -e " 5 修改面板访问端口: \033[36m$db_port\033[0m" - echo -e " 6 设置面板访问密码: \033[36m$secret\033[0m" - echo -e " 7 修改默认端口过滤: \033[36m$multiport\033[0m" - echo -e " 8 自定义本机host地址: \033[36m$host\033[0m" - echo -e " 9 自定义路由表: \033[36m$table,$((table + 1))\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - xport=mix_port - inputport - ;; - 2) - echo ----------------------------------------------- - echo -e "格式必须是\033[32m 用户名:密码 \033[0m的形式,注意用小写冒号分隔!" - echo -e "请尽量不要使用特殊符号!避免产生未知错误!" - echo "输入 0 删除密码" - echo ----------------------------------------------- - read -p "请输入Http/Sock5用户名及密码 > " input - if [ "$input" = "0" ]; then - authentication="" - setconfig authentication - echo 密码已移除! - else - if [ "$local_proxy" = "已开启" -a "$local_type" = "环境变量" ]; then - echo ----------------------------------------------- - echo -e "\033[33m请先禁用本机代理功能或使用增强模式!\033[0m" - sleep 1 - else - authentication=$(echo $input | grep :) - if [ -n "$authentication" ]; then - setconfig authentication "'$authentication'" - echo -e "\033[32m设置成功!!!\033[0m" - else - echo -e "\033[31m输入有误,请重新输入!\033[0m" - fi - fi - fi - setport - ;; - 3) - xport=redir_port - inputport - ;; - 4) - xport=dns_port - inputport - ;; - 5) - xport=db_port - inputport - ;; - 6) - read -p "请输入面板访问密码(输入0删除密码) > " secret - if [ -n "$secret" ]; then - [ "$secret" = "0" ] && secret="" - setconfig secret $secret - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - 7) - echo ----------------------------------------------- - echo -e "需配合\033[32m仅代理常用端口\033[0m功能使用" - echo -e "多个端口请用小写逗号分隔,例如:\033[33m143,80,443\033[0m" - echo -e "输入 0 重置为默认端口" - echo ----------------------------------------------- - read -p "请输入需要指定代理的端口 > " multiport - if [ -n "$multiport" ]; then - [ "$multiport" = "0" ] && multiport="22,80,143,194,443,465,587,853,993,995,5222,8080,8443" - common_ports=已开启 - setconfig multiport $multiport - setconfig common_ports $common_ports - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - 8) - echo ----------------------------------------------- - echo -e "\033[33m如果你的局域网网段不是192.168.x或172.16.x或10.x开头,请务必修改!\033[0m" - echo -e "\033[31m设置后如本机host地址有变动,请务必重新修改!\033[0m" - echo ----------------------------------------------- - read -p "请输入自定义host地址(输入0移除自定义host) > " host - if [ "$host" = "0" ]; then - host="" - setconfig host $host - echo -e "\033[32m已经移除自定义host地址,请重新运行脚本以自动获取host!!!\033[0m" - exit 0 - elif [ -n "$(echo $host | grep -E -o '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>){2}\.\<([1-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>')" ]; then - setconfig host $host - echo -e "\033[32m设置成功!!!\033[0m" - else - host="" - echo -e "\033[31m输入错误,请仔细核对!!!\033[0m" - fi - sleep 1 - setport - ;; - 9) - echo ----------------------------------------------- - echo -e "\033[33m仅限Tproxy、Tun或混合模式路由表出现冲突时才需要设置!\033[0m" - read -p "请输入路由表地址(不明勿动!建议102-125之间) > " table - if [ -n "$table" ]; then - [ "$table" = "0" ] && table="100" - setconfig table $table - echo -e "\033[32m设置成功!!!\033[0m" - fi - setport - ;; - *) - errornum - ;; - esac + . $CFG_PATH >/dev/null + [ -z "$secret" ] && secret=未设置 + [ -z "$table" ] && table=100 + [ -z "$authentication" ] && auth=未设置 || auth=****** + inputport() { + read -p "请输入端口号(1-65535) > " portx + if [ -z "$portx" ]; then + setport + elif [ $portx -gt 65535 -o $portx -le 1 ]; then + echo -e "\033[31m输入错误!请输入正确的数值(1-65535)!\033[0m" + inputport + elif [ -n "$(echo "|$mix_port|$redir_port|$dns_port|$db_port|" | grep "|$portx|")" ]; then + echo -e "\033[31m输入错误!请不要输入重复的端口!\033[0m" + inputport + elif [ -n "$(netstat -ntul | grep ":$portx ")" ]; then + echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" + inputport + else + setconfig $xport $portx + echo -e "\033[32m设置成功!!!\033[0m" + setport + fi + } + echo "-----------------------------------------------" + echo -e " 1 修改Http/Sock5端口: \033[36m$mix_port\033[0m" + echo -e " 2 设置Http/Sock5密码: \033[36m$auth\033[0m" + echo -e " 3 修改Redir/Tproxy端口:\033[36m$redir_port,$((redir_port + 1))\033[0m" + echo -e " 4 修改DNS监听端口: \033[36m$dns_port\033[0m" + echo -e " 5 修改面板访问端口: \033[36m$db_port\033[0m" + echo -e " 6 设置面板访问密码: \033[36m$secret\033[0m" + echo -e " 7 修改默认端口过滤: \033[36m$multiport\033[0m" + echo -e " 8 自定义本机host地址: \033[36m$host\033[0m" + echo -e " 9 自定义路由表: \033[36m$table,$((table + 1))\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + xport=mix_port + inputport + ;; + 2) + echo "-----------------------------------------------" + echo -e "格式必须是\033[32m 用户名:密码 \033[0m的形式,注意用小写冒号分隔!" + echo -e "请尽量不要使用特殊符号!避免产生未知错误!" + echo "输入 0 删除密码" + echo "-----------------------------------------------" + read -p "请输入Http/Sock5用户名及密码 > " input + if [ "$input" = "0" ]; then + authentication="" + setconfig authentication + echo 密码已移除! + else + if [ "$local_proxy" = "已开启" -a "$local_type" = "环境变量" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m请先禁用本机代理功能或使用增强模式!\033[0m" + sleep 1 + else + authentication=$(echo $input | grep :) + if [ -n "$authentication" ]; then + setconfig authentication "'$authentication'" + echo -e "\033[32m设置成功!!!\033[0m" + else + echo -e "\033[31m输入有误,请重新输入!\033[0m" + fi + fi + fi + setport + ;; + 3) + xport=redir_port + inputport + ;; + 4) + xport=dns_port + inputport + ;; + 5) + xport=db_port + inputport + ;; + 6) + read -p "请输入面板访问密码(输入0删除密码) > " secret + if [ -n "$secret" ]; then + [ "$secret" = "0" ] && secret="" + setconfig secret $secret + echo -e "\033[32m设置成功!!!\033[0m" + fi + setport + ;; + 7) + echo "-----------------------------------------------" + echo -e "需配合\033[32m仅代理常用端口\033[0m功能使用" + echo -e "多个端口请用小写逗号分隔,例如:\033[33m143,80,443\033[0m" + echo -e "输入 0 重置为默认端口" + echo "-----------------------------------------------" + read -p "请输入需要指定代理的端口 > " multiport + if [ -n "$multiport" ]; then + [ "$multiport" = "0" ] && multiport="22,80,143,194,443,465,587,853,993,995,5222,8080,8443" + common_ports=已开启 + setconfig multiport $multiport + setconfig common_ports $common_ports + echo -e "\033[32m设置成功!!!\033[0m" + fi + setport + ;; + 8) + echo "-----------------------------------------------" + echo -e "\033[33m如果你的局域网网段不是192.168.x或172.16.x或10.x开头,请务必修改!\033[0m" + echo -e "\033[31m设置后如本机host地址有变动,请务必重新修改!\033[0m" + echo "-----------------------------------------------" + read -p "请输入自定义host地址(输入0移除自定义host) > " host + if [ "$host" = "0" ]; then + host="" + setconfig host $host + echo -e "\033[32m已经移除自定义host地址,请重新运行脚本以自动获取host!!!\033[0m" + exit 0 + elif [ -n "$(echo $host | grep -E -o '\<([1-9]|[1-9][0-9]|1[0-9]{2}|2[01][0-9]|22[0-3])\>(\.\<([0-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\>){2}\.\<([1-9]|[0-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-4])\>')" ]; then + setconfig host $host + echo -e "\033[32m设置成功!!!\033[0m" + else + host="" + echo -e "\033[31m输入错误,请仔细核对!!!\033[0m" + fi + sleep 1 + setport + ;; + 9) + echo "-----------------------------------------------" + echo -e "\033[33m仅限Tproxy、Tun或混合模式路由表出现冲突时才需要设置!\033[0m" + read -p "请输入路由表地址(不明勿动!建议102-125之间) > " table + if [ -n "$table" ]; then + [ "$table" = "0" ] && table="100" + setconfig table $table + echo -e "\033[32m设置成功!!!\033[0m" + fi + setport + ;; + *) + errornum + ;; + esac } setdns() { #DNS详细设置 - [ -z "$dns_nameserver" ] && dns_nameserver='180.184.1.1, 1.2.4.8' - [ -z "$dns_fallback" ] && dns_fallback="1.1.1.1, 8.8.8.8" - [ -z "$dns_resolver" ] && dns_resolver="223.5.5.5, 2400:3200::1" - [ -z "$hosts_opt" ] && hosts_opt=已启用 - [ -z "$dns_protect" ] && dns_protect=ON - [ -z "$dns_redir" ] && dns_redir=未开启 - [ -z "$dns_no" ] && dns_no=未禁用 - echo ----------------------------------------------- - echo -e "当前基础DNS:\033[32m$dns_nameserver\033[0m" - echo -e "PROXY-DNS:\033[36m$dns_fallback\033[0m" - echo -e "解析DNS:\033[33m$dns_resolver\033[0m" - echo -e "多个DNS地址请用\033[30;47m“|”\033[0m或者\033[30;47m“, ”\033[0m分隔输入" - echo -e "\033[33m必须拥有本地根证书文件才能使用dot/doh类型的加密dns\033[0m" - echo -e "\033[31m注意singbox内核只有首个dns会被加载!\033[0m" - echo ----------------------------------------------- - echo -e " 1 修改\033[32m基础DNS\033[0m" - echo -e " 2 修改\033[36mPROXY-DNS\033[0m(该DNS查询会经过节点)" - echo -e " 3 修改\033[33m解析DNS\033[0m(必须是IP,用于解析其他DNS)" - echo -e " 4 DNS防泄漏: \033[36m$dns_protect\033[0m ———启用时少量网站可能连接卡顿" - echo -e " 5 hosts优化: \033[36m$hosts_opt\033[0m ———调用本机hosts并劫持NTP服务" - #echo -e " 6 Dnsmasq转发:\033[36m$dns_redir\033[0m ———不推荐使用" - echo -e " 7 禁用DNS劫持:\033[36m$dns_no\033[0m ———搭配第三方DNS使用" - echo -e " 8 一键配置\033[32m加密DNS\033[0m" - echo -e " 9 \033[33m重置\033[0m默认DNS配置" - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case "$num" in - 0) - ;; - 1) - read -p "请输入新的DNS > " dns_nameserver - dns_nameserver=$(echo $dns_nameserver | sed 's#|#\,\ #g') - if [ -n "$dns_nameserver" ]; then - setconfig dns_nameserver "'$dns_nameserver'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 2) - read -p "请输入新的DNS > " dns_fallback - dns_fallback=$(echo $dns_fallback | sed 's/|/\,\ /g') - if [ -n "$dns_fallback" ]; then - setconfig dns_fallback "'$dns_fallback'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 3) - read -p "请输入新的DNS > " text - if echo "$text" | grep -qE '://.*::'; then - echo -e "\033[31m此选项暂不支持ipv6加密DNS!!!\033[0m" - elif [ -n "$text" ]; then - dns_resolver=$(echo $text | sed 's/|/\,\ /g') - setconfig dns_resolver "'$dns_resolver'" - echo -e "\033[32m设置成功!!!\033[0m" - fi - sleep 1 - setdns - ;; - 4) - [ "$dns_protect" = "ON" ] && dns_protect=OFF || dns_protect=ON - setconfig dns_protect $dns_protect - setdns - ;; - 5) - echo ----------------------------------------------- - if [ "$hosts_opt" = "已启用" ]; then - hosts_opt=未启用 - echo -e "\033[32m已禁用hosts优化功能!!!\033[0m" - else - hosts_opt=已启用 - echo -e "\033[33m已启用hosts优化功能!!!\033[0m" - fi - setconfig hosts_opt $hosts_opt - sleep 1 - setdns - ;; - 6) - echo ----------------------------------------------- - if [ "$dns_redir" = "未开启" ]; then - echo -e "\033[31m将使用OpenWrt中Dnsmasq插件自带的DNS转发功能转发DNS请求至内核!\033[0m" - echo -e "\033[33m启用后将禁用本插件自带的iptables转发功能\033[0m" - dns_redir=已开启 - echo -e "\033[32m已启用Dnsmasq转发DNS功能!!!\033[0m" - else - uci del dhcp.@dnsmasq[-1].server - uci set dhcp.@dnsmasq[0].noresolv=0 - uci commit dhcp - /etc/init.d/dnsmasq restart - echo -e "\033[33m禁用成功!!如有报错请重启设备!\033[0m" - dns_redir=未开启 - fi - setconfig dns_redir $dns_redir - sleep 1 - setdns - ;; - 7) - echo ----------------------------------------------- - if [ "$dns_no" = "未禁用" ]; then - echo -e "\033[31m仅限搭配其他DNS服务(比如dnsmasq、smartDNS)时使用!\033[0m" - dns_no=已禁用 - echo -e "\033[32m已禁用DNS劫持!!!\033[0m" - else - dns_no=未禁用 - echo -e "\033[33m已启用DNS劫持!!!\033[0m" - fi - setconfig dns_no $dns_no - sleep 1 - setdns - ;; - 8) - echo ----------------------------------------------- - openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" - if [ -s "$openssldir/certs/ca-certificates.crt" ] || [ -s "/etc/ssl/certs/ca-certificates.crt" ] || \ - echo "$crashcore" |grep -qE 'meta|singbox'; then - dns_nameserver='https://doh.360.cn/dns-query, https://dns.alidns.com/dns-query, https://doh.pub/dns-query' - dns_fallback='https://cloudflare-dns.com/dns-query, https://dns.google/dns-query, https://doh.opendns.com/dns-query' - dns_resolver='https://223.5.5.5/dns-query, 2400:3200::1' - setconfig dns_nameserver "'$dns_nameserver'" - setconfig dns_fallback "'$dns_fallback'" - setconfig dns_resolver "'$dns_resolver'" - echo -e "\033[32m已设置加密DNS,如出现DNS解析问题,请尝试重置DNS配置!\033[0m" - else - echo -e "\033[31m找不到根证书文件,无法启用加密DNS,Linux系统请自行搜索安装OpenSSL的方式!\033[0m" - fi - sleep 1 - setdns - ;; - 9) - dns_nameserver= - dns_fallback= - dns_resolver= - setconfig dns_nameserver - setconfig dns_fallback - setconfig dns_resolver - echo -e "\033[33mDNS配置已重置!!!\033[0m" - sleep 1 - setdns - ;; - *) - errornum - sleep 1 - ;; - esac + [ -z "$dns_nameserver" ] && dns_nameserver='180.184.1.1, 1.2.4.8' + [ -z "$dns_fallback" ] && dns_fallback="1.1.1.1, 8.8.8.8" + [ -z "$dns_resolver" ] && dns_resolver="223.5.5.5, 2400:3200::1" + [ -z "$hosts_opt" ] && hosts_opt=已启用 + [ -z "$dns_protect" ] && dns_protect=ON + [ -z "$dns_redir" ] && dns_redir=未开启 + [ -z "$dns_no" ] && dns_no=未禁用 + echo "-----------------------------------------------" + echo -e "当前基础DNS:\033[32m$dns_nameserver\033[0m" + echo -e "PROXY-DNS:\033[36m$dns_fallback\033[0m" + echo -e "解析DNS:\033[33m$dns_resolver\033[0m" + echo -e "多个DNS地址请用\033[30;47m“|”\033[0m或者\033[30;47m“, ”\033[0m分隔输入" + echo -e "\033[33m必须拥有本地根证书文件才能使用dot/doh类型的加密dns\033[0m" + echo -e "\033[31m注意singbox内核只有首个dns会被加载!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 修改\033[32m基础DNS\033[0m" + echo -e " 2 修改\033[36mPROXY-DNS\033[0m(该DNS查询会经过节点)" + echo -e " 3 修改\033[33m解析DNS\033[0m(必须是IP,用于解析其他DNS)" + echo -e " 4 DNS防泄漏: \033[36m$dns_protect\033[0m ———启用时少量网站可能连接卡顿" + echo -e " 5 hosts优化: \033[36m$hosts_opt\033[0m ———调用本机hosts并劫持NTP服务" + #echo -e " 6 Dnsmasq转发:\033[36m$dns_redir\033[0m ———不推荐使用" + echo -e " 7 禁用DNS劫持:\033[36m$dns_no\033[0m ———搭配第三方DNS使用" + echo -e " 8 一键配置\033[32m加密DNS\033[0m" + echo -e " 9 \033[33m重置\033[0m默认DNS配置" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + read -p "请输入新的DNS > " dns_nameserver + dns_nameserver=$(echo $dns_nameserver | sed 's#|#\,\ #g') + if [ -n "$dns_nameserver" ]; then + setconfig dns_nameserver "'$dns_nameserver'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + setdns + ;; + 2) + read -p "请输入新的DNS > " dns_fallback + dns_fallback=$(echo $dns_fallback | sed 's/|/\,\ /g') + if [ -n "$dns_fallback" ]; then + setconfig dns_fallback "'$dns_fallback'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + setdns + ;; + 3) + read -p "请输入新的DNS > " text + if echo "$text" | grep -qE '://.*::'; then + echo -e "\033[31m此选项暂不支持ipv6加密DNS!!!\033[0m" + elif [ -n "$text" ]; then + dns_resolver=$(echo $text | sed 's/|/\,\ /g') + setconfig dns_resolver "'$dns_resolver'" + echo -e "\033[32m设置成功!!!\033[0m" + fi + sleep 1 + setdns + ;; + 4) + [ "$dns_protect" = "ON" ] && dns_protect=OFF || dns_protect=ON + setconfig dns_protect $dns_protect + setdns + ;; + 5) + echo "-----------------------------------------------" + if [ "$hosts_opt" = "已启用" ]; then + hosts_opt=未启用 + echo -e "\033[32m已禁用hosts优化功能!!!\033[0m" + else + hosts_opt=已启用 + echo -e "\033[33m已启用hosts优化功能!!!\033[0m" + fi + setconfig hosts_opt $hosts_opt + sleep 1 + setdns + ;; + 6) + echo "-----------------------------------------------" + if [ "$dns_redir" = "未开启" ]; then + echo -e "\033[31m将使用OpenWrt中Dnsmasq插件自带的DNS转发功能转发DNS请求至内核!\033[0m" + echo -e "\033[33m启用后将禁用本插件自带的iptables转发功能\033[0m" + dns_redir=已开启 + echo -e "\033[32m已启用Dnsmasq转发DNS功能!!!\033[0m" + else + uci del dhcp.@dnsmasq[-1].server + uci set dhcp.@dnsmasq[0].noresolv=0 + uci commit dhcp + /etc/init.d/dnsmasq restart + echo -e "\033[33m禁用成功!!如有报错请重启设备!\033[0m" + dns_redir=未开启 + fi + setconfig dns_redir $dns_redir + sleep 1 + setdns + ;; + 7) + echo "-----------------------------------------------" + if [ "$dns_no" = "未禁用" ]; then + echo -e "\033[31m仅限搭配其他DNS服务(比如dnsmasq、smartDNS)时使用!\033[0m" + dns_no=已禁用 + echo -e "\033[32m已禁用DNS劫持!!!\033[0m" + else + dns_no=未禁用 + echo -e "\033[33m已启用DNS劫持!!!\033[0m" + fi + setconfig dns_no $dns_no + sleep 1 + setdns + ;; + 8) + echo "-----------------------------------------------" + openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" + if [ -s "$openssldir/certs/ca-certificates.crt" ] || [ -s "/etc/ssl/certs/ca-certificates.crt" ] || + echo "$crashcore" | grep -qE 'meta|singbox'; then + dns_nameserver='https://doh.360.cn/dns-query, https://dns.alidns.com/dns-query, https://doh.pub/dns-query' + dns_fallback='https://cloudflare-dns.com/dns-query, https://dns.google/dns-query, https://doh.opendns.com/dns-query' + dns_resolver='https://223.5.5.5/dns-query, 2400:3200::1' + setconfig dns_nameserver "'$dns_nameserver'" + setconfig dns_fallback "'$dns_fallback'" + setconfig dns_resolver "'$dns_resolver'" + echo -e "\033[32m已设置加密DNS,如出现DNS解析问题,请尝试重置DNS配置!\033[0m" + else + echo -e "\033[31m找不到根证书文件,无法启用加密DNS,Linux系统请自行搜索安装OpenSSL的方式!\033[0m" + fi + sleep 1 + setdns + ;; + 9) + dns_nameserver= + dns_fallback= + dns_resolver= + setconfig dns_nameserver + setconfig dns_fallback + setconfig dns_resolver + echo -e "\033[33mDNS配置已重置!!!\033[0m" + sleep 1 + setdns + ;; + *) + errornum + sleep 1 + ;; + esac } setipv6() { #ipv6设置 - [ -z "$ipv6_redir" ] && ipv6_redir=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 - echo ----------------------------------------------- - echo -e " 1 ipv6透明代理: \033[36m$ipv6_redir\033[0m ——代理ipv6流量" - [ "$disoverride" != "1" ] && echo -e " 2 ipv6-DNS解析: \033[36m$ipv6_dns\033[0m ——决定内置DNS是否返回ipv6地址" - echo -e " 3 CNV6绕过内核: \033[36m$cn_ipv6_route\033[0m ——优化性能,不兼容fake-ip" - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - 0) ;; - 1) - if [ "$ipv6_redir" = "未开启" ]; then - ipv6_support=已开启 - ipv6_redir=已开启 - sleep 2 - else - ipv6_redir=未开启 - fi - setconfig ipv6_redir $ipv6_redir - setconfig ipv6_support $ipv6_support - setipv6 - ;; - 2) - [ "$ipv6_dns" = "未开启" ] && ipv6_dns=已开启 || ipv6_dns=未开启 - setconfig ipv6_dns $ipv6_dns - setipv6 - ;; - 3) - if [ "$ipv6_redir" = "未开启" ]; then - ipv6_support=已开启 - ipv6_redir=已开启 - setconfig ipv6_redir $ipv6_redir - setconfig ipv6_support $ipv6_support - fi - if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = nftables ]; then - [ "$cn_ipv6_route" = "未开启" ] && cn_ipv6_route=已开启 || cn_ipv6_route=未开启 - setconfig cn_ipv6_route $cn_ipv6_route - else - echo -e "\033[31m当前设备缺少ipset模块或防火墙未使用nftables,无法启用绕过功能!!\033[0m" - sleep 1 - fi - setipv6 - ;; - *) - errornum - ;; - esac + [ -z "$ipv6_redir" ] && ipv6_redir=未开启 + [ -z "$ipv6_dns" ] && ipv6_dns=已开启 + [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 + echo "-----------------------------------------------" + echo -e " 1 ipv6透明代理: \033[36m$ipv6_redir\033[0m ——代理ipv6流量" + [ "$disoverride" != "1" ] && echo -e " 2 ipv6-DNS解析: \033[36m$ipv6_dns\033[0m ——决定内置DNS是否返回ipv6地址" + echo -e " 3 CNV6绕过内核: \033[36m$cn_ipv6_route\033[0m ——优化性能,不兼容fake-ip" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + if [ "$ipv6_redir" = "未开启" ]; then + ipv6_support=已开启 + ipv6_redir=已开启 + sleep 2 + else + ipv6_redir=未开启 + fi + setconfig ipv6_redir $ipv6_redir + setconfig ipv6_support $ipv6_support + setipv6 + ;; + 2) + [ "$ipv6_dns" = "未开启" ] && ipv6_dns=已开启 || ipv6_dns=未开启 + setconfig ipv6_dns $ipv6_dns + setipv6 + ;; + 3) + if [ "$ipv6_redir" = "未开启" ]; then + ipv6_support=已开启 + ipv6_redir=已开启 + setconfig ipv6_redir $ipv6_redir + setconfig ipv6_support $ipv6_support + fi + if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = nftables ]; then + [ "$cn_ipv6_route" = "未开启" ] && cn_ipv6_route=已开启 || cn_ipv6_route=未开启 + setconfig cn_ipv6_route $cn_ipv6_route + else + echo -e "\033[31m当前设备缺少ipset模块或防火墙未使用nftables,无法启用绕过功能!!\033[0m" + sleep 1 + fi + setipv6 + ;; + *) + errornum + ;; + esac } setfirewall() { #防火墙设置 - set_cust_host_ipv4() { - [ -z "$replace_default_host_ipv4" ] && replace_default_host_ipv4="未启用" + set_cust_host_ipv4() { + [ -z "$replace_default_host_ipv4" ] && replace_default_host_ipv4="未启用" - echo ----------------------------------------------- - echo -e "当前默认透明路由的网段为: \033[32m$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'br' | grep -v 'iot' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ' && echo) \033[0m" - echo -e "当前已添加的自定义网段为:\033[36m$cust_host_ipv4\033[0m" - echo ----------------------------------------------- - echo -e " 1 移除所有自定义网段" - echo -e " 2 使用自定义网段覆盖默认网段 \033[36m$replace_default_host_ipv4\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应的序号或需要额外添加的网段 > " text - case $text in - 2) - if [ "$replace_default_host_ipv4" == "未启用" ]; then - replace_default_host_ipv4="已启用" - else - replace_default_host_ipv4="未启用" - fi - setconfig replace_default_host_ipv4 "$replace_default_host_ipv4" - set_cust_host_ipv4 - ;; - 1) - unset cust_host_ipv4 - setconfig cust_host_ipv4 - set_cust_host_ipv4 - ;; - 0) ;; - *) - if [ -n "$(echo $text | grep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}'$)" -a -z "$(echo $cust_host_ipv4 | grep "$text")" ]; then - cust_host_ipv4="$cust_host_ipv4 $text" - setconfig cust_host_ipv4 "'$cust_host_ipv4'" - else - echo ----------------------------------------------- - echo -e "\033[31m请输入正确的网段地址!\033[0m" - fi - sleep 1 - set_cust_host_ipv4 - ;; - esac - } - [ -z "$public_support" ] && public_support=未开启 - [ -z "$public_mixport" ] && public_mixport=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 - echo ----------------------------------------------- - echo -e " 1 公网访问Dashboard面板: \033[36m$public_support\033[0m" - echo -e " 2 公网访问Socks/Http代理: \033[36m$public_mixport\033[0m" - echo -e " 3 自定义透明路由ipv4网段: 适合vlan等复杂网络环境" - echo -e " 4 自定义保留地址ipv4网段: 需要以保留地址为访问目标的环境" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - 1) - if [ "$public_support" = "未开启" ]; then - public_support=已开启 - else - public_support=未开启 - fi - setconfig public_support $public_support - setfirewall - ;; - 2) - if [ "$public_mixport" = "未开启" ]; then - if [ "$mix_port" = "7890" -o -z "$authentication" ]; then - echo ----------------------------------------------- - echo -e "\033[33m为了安全考虑,请先修改默认Socks/Http端口并设置代理密码\033[0m" - sleep 1 - setport - else - public_mixport=已开启 - fi - else - public_mixport=未开启 - fi - setconfig public_mixport $public_mixport - setfirewall - ;; - 3) - set_cust_host_ipv4 - setfirewall - ;; - 4) - [ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" - echo -e "当前网段:\033[36m$reserve_ipv4\033[0m" - echo -e "\033[33m地址必须是空格分隔,错误的设置可能导致网络回环或启动报错,请务必谨慎!\033[0m" - read -p "请输入 > " text - if [ -n "$( - echo $text | grep -E "(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[1-2]?[0-9]))( +|$)+" - )" ]; then - reserve_ipv4="$text" - echo -e "已将保留地址网段设为:\033[32m$reserve_ipv4\033[0m" - setconfig reserve_ipv4 "'$reserve_ipv4'" - else - echo -e "\033[31m输入有误,操作已取消!\033[0m" - fi - sleep 1 - setfirewall - ;; - *) - errornum - ;; - esac + echo "-----------------------------------------------" + echo -e "当前默认透明路由的网段为: \033[32m$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'br' | grep -v 'iot' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ' && echo) \033[0m" + echo -e "当前已添加的自定义网段为:\033[36m$cust_host_ipv4\033[0m" + echo "-----------------------------------------------" + echo -e " 1 移除所有自定义网段" + echo -e " 2 使用自定义网段覆盖默认网段 \033[36m$replace_default_host_ipv4\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应的序号或需要额外添加的网段 > " text + case "$text" in + 2) + if [ "$replace_default_host_ipv4" == "未启用" ]; then + replace_default_host_ipv4="已启用" + else + replace_default_host_ipv4="未启用" + fi + setconfig replace_default_host_ipv4 "$replace_default_host_ipv4" + set_cust_host_ipv4 + ;; + 1) + unset cust_host_ipv4 + setconfig cust_host_ipv4 + set_cust_host_ipv4 + ;; + 0) ;; + *) + if [ -n "$(echo $text | grep -Eo '^([0-9]{1,3}\.){3}[0-9]{1,3}/[0-9]{1,2}'$)" -a -z "$(echo $cust_host_ipv4 | grep "$text")" ]; then + cust_host_ipv4="$cust_host_ipv4 $text" + setconfig cust_host_ipv4 "'$cust_host_ipv4'" + else + echo "-----------------------------------------------" + echo -e "\033[31m请输入正确的网段地址!\033[0m" + fi + sleep 1 + set_cust_host_ipv4 + ;; + esac + } + [ -z "$public_support" ] && public_support=未开启 + [ -z "$public_mixport" ] && public_mixport=未开启 + [ -z "$ipv6_dns" ] && ipv6_dns=已开启 + [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 + echo "-----------------------------------------------" + echo -e " 1 公网访问Dashboard面板: \033[36m$public_support\033[0m" + echo -e " 2 公网访问Socks/Http代理: \033[36m$public_mixport\033[0m" + echo -e " 3 自定义透明路由ipv4网段: 适合vlan等复杂网络环境" + echo -e " 4 自定义保留地址ipv4网段: 需要以保留地址为访问目标的环境" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 1) + if [ "$public_support" = "未开启" ]; then + public_support=已开启 + else + public_support=未开启 + fi + setconfig public_support $public_support + setfirewall + ;; + 2) + if [ "$public_mixport" = "未开启" ]; then + if [ "$mix_port" = "7890" -o -z "$authentication" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m为了安全考虑,请先修改默认Socks/Http端口并设置代理密码\033[0m" + sleep 1 + setport + else + public_mixport=已开启 + fi + else + public_mixport=未开启 + fi + setconfig public_mixport $public_mixport + setfirewall + ;; + 3) + set_cust_host_ipv4 + setfirewall + ;; + 4) + [ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4" + echo -e "当前网段:\033[36m$reserve_ipv4\033[0m" + echo -e "\033[33m地址必须是空格分隔,错误的设置可能导致网络回环或启动报错,请务必谨慎!\033[0m" + read -p "请输入 > " text + if [ -n "$( + echo $text | grep -E "(((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])\.){3}(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])/(3[0-2]|[1-2]?[0-9]))( +|$)+" + )" ]; then + reserve_ipv4="$text" + echo -e "已将保留地址网段设为:\033[32m$reserve_ipv4\033[0m" + setconfig reserve_ipv4 "'$reserve_ipv4'" + else + echo -e "\033[31m输入有误,操作已取消!\033[0m" + fi + sleep 1 + setfirewall + ;; + *) + errornum + ;; + esac } checkport() { #自动检查端口冲突 - for portx in $dns_port $mix_port $redir_port $((redir_port + 1)) $db_port; do - if [ -n "$(netstat -ntul 2>&1 | grep ':$portx ')" ]; then - echo ----------------------------------------------- - echo -e "检测到端口【$portx】被以下进程占用!内核可能无法正常启动!\033[33m" - echo $(netstat -ntul | grep :$portx | head -n 1) - echo -e "\033[0m-----------------------------------------------" - echo -e "\033[36m请修改默认端口配置!\033[0m" - setport - . $CFG_PATH >/dev/null - checkport - fi - done + for portx in $dns_port $mix_port $redir_port $((redir_port + 1)) $db_port; do + if [ -n "$(netstat -ntul 2>&1 | grep ':$portx ')" ]; then + echo "-----------------------------------------------" + echo -e "检测到端口【$portx】被以下进程占用!内核可能无法正常启动!\033[33m" + echo $(netstat -ntul | grep :$portx | head -n 1) + echo -e "\033[0m-----------------------------------------------" + echo -e "\033[36m请修改默认端口配置!\033[0m" + setport + . $CFG_PATH >/dev/null + checkport + fi + done } macfilter() { #局域网设备过滤 - get_devinfo() { - dev_ip=$(cat $dhcpdir | grep " $dev " | awk '{print $3}') && [ -z "$dev_ip" ] && dev_ip=$dev - dev_mac=$(cat $dhcpdir | grep " $dev " | awk '{print $2}') && [ -z "$dev_mac" ] && dev_mac=$dev - dev_name=$(cat $dhcpdir | grep " $dev " | awk '{print $4}') && [ -z "$dev_name" ] && dev_name='未知设备' - } - add_mac() { - echo ----------------------------------------------- - echo 已添加的mac地址: - cat ${CRASHDIR}/configs/mac 2>/dev/null - echo ----------------------------------------------- - echo -e "\033[33m序号 设备IP 设备mac地址 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$2,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入mac地址时仅支持\033[32mxx:xx:xx:xx:xx:xx\033[0m的形式" - echo -e " 0 或回车 结束添加" - echo ----------------------------------------------- - read -p "请输入对应序号或直接输入mac地址 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$num")" ]; then - echo $num | grep -oE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' >>${CRASHDIR}/configs/mac - else - echo ----------------------------------------------- - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - macadd=$(cat $dhcpdir | awk '{print $2}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$macadd")" ]; then - echo $macadd >>${CRASHDIR}/configs/mac - else - echo ----------------------------------------------- - echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" - fi - add_mac - else - echo ----------------------------------------------- - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_mac - fi - } - add_ip() { - echo ----------------------------------------------- - echo "已添加的IP地址(段):" - cat ${CRASHDIR}/configs/ip_filter 2>/dev/null - echo ----------------------------------------------- - echo -e "\033[33m序号 设备IP 设备名称\033[32m" - cat $dhcpdir | awk '{print " "NR" "$3,$4}' - echo -e "\033[0m-----------------------------------------------" - echo -e "手动输入时仅支持\033[32m 192.168.1.0/24\033[0m 或 \033[32m192.168.1.0\033[0m 的形式" - echo -e "不支持ipv6地址过滤,如有需求请使用mac地址过滤" - echo -e " 0 或回车 结束添加" - echo ----------------------------------------------- - read -p "请输入对应序号或直接输入IP地址段 > " num - if [ -z "$num" -o "$num" = 0 ]; then - i= - elif [ -n "$(echo $num | grep -aE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$')" ]; then - if [ -z "$(cat ${CRASHDIR}/configs/ip_filter | grep -E "$num")" ]; then - echo $num | grep -oE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$' >>${CRASHDIR}/configs/ip_filter - else - echo ----------------------------------------------- - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then - ipadd=$(cat $dhcpdir | awk '{print $3}' | sed -n "$num"p) - if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$ipadd")" ]; then - echo $ipadd >>${CRASHDIR}/configs/ip_filter - else - echo ----------------------------------------------- - echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" - fi - add_ip - else - echo ----------------------------------------------- - echo -e "\033[31m输入有误,请重新输入!\033[0m" - add_ip - fi - } - del_all() { - echo ----------------------------------------------- - if [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ]; then - echo -e "\033[31m列表中没有需要移除的设备!\033[0m" - sleep 1 - else - echo -e "请选择需要移除的设备:\033[36m" - echo -e "\033[33m 设备IP 设备mac地址 设备名称\033[0m" - i=1 - for dev in $(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e " $i \033[32m$dev_ip \033[36m$dev_mac \033[32m$dev_name\033[0m" - i=$((i + 1)) - done - echo ----------------------------------------------- - echo -e "\033[0m 0 或回车 结束删除" - read -p "请输入需要移除的设备的对应序号 > " num - mac_filter_rows=$(cat ${CRASHDIR}/configs/mac 2>/dev/null | wc -l) - ip_filter_rows=$(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null | wc -l) - if [ -z "$num" ] || [ "$num" -le 0 ]; then - n= - elif [ $num -le $mac_filter_rows ]; then - sed -i "${num}d" ${CRASHDIR}/configs/mac - echo ----------------------------------------------- - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - elif [ $num -le $((mac_filter_rows + ip_filter_rows)) ]; then - num=$((num - mac_filter_rows)) - sed -i "${num}d" ${CRASHDIR}/configs/ip_filter - echo ----------------------------------------------- - echo -e "\033[32m对应设备已移除!\033[0m" - del_all - else - echo ----------------------------------------------- - echo -e "\033[31m输入有误,请重新输入!\033[0m" - del_all - fi - fi - } - echo ----------------------------------------------- - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcp/dhcpd.leases ] && dhcpdir='/var/lib/dhcp/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /var/lib/dhcpd/dhcpd.leases ] && dhcpdir='/var/lib/dhcpd/dhcpd.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dhcp.leases ] && dhcpdir='/tmp/dhcp.leases' - [ -z "$dhcpdir" ] && [ -f /tmp/dnsmasq.leases ] && dhcpdir='/tmp/dnsmasq.leases' - [ -z "$dhcpdir" ] && dhcpdir='/dev/null' - [ -z "$macfilter_type" ] && macfilter_type='黑名单' - if [ "$macfilter_type" = "黑名单" ]; then - macfilter_over='白名单' - macfilter_scrip='不' - else - macfilter_over='黑名单' - macfilter_scrip='' - fi - ###### - echo -e "\033[30;47m请在此添加或移除设备\033[0m" - echo -e "当前过滤方式为:\033[33m$macfilter_type模式\033[0m" - echo -e "仅列表内设备流量\033[36m$macfilter_scrip经过\033[0m内核" - if [ -n "$(cat ${CRASHDIR}/configs/mac)" ]; then - echo ----------------------------------------------- - echo -e "当前已过滤设备为:\033[36m" - echo -e "\033[33m 设备mac/ip地址 设备名称\033[0m" - for dev in $(cat ${CRASHDIR}/configs/mac 2>/dev/null); do - get_devinfo - echo -e "\033[36m$dev_mac \033[0m$dev_name" - done - for dev in $(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null); do - get_devinfo - echo -e "\033[32m$dev_ip \033[0m$dev_name" - done - echo ----------------------------------------------- - fi - echo -e " 1 切换为\033[33m$macfilter_over模式\033[0m" - echo -e " 2 \033[32m添加指定设备(mac地址)\033[0m" - echo -e " 3 \033[32m添加指定设备(IP地址/网段)\033[0m" - echo -e " 4 \033[36m移除指定设备\033[0m" - echo -e " 9 \033[31m清空整个列表\033[0m" - echo -e " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 1) - macfilter_type=$macfilter_over - setconfig macfilter_type $macfilter_type - echo ----------------------------------------------- - echo -e "\033[32m已切换为$macfilter_type模式!\033[0m" - macfilter - ;; - 2) - add_mac - macfilter - ;; - 3) - add_ip - macfilter - ;; - 4) - del_all - macfilter - ;; - 9) - : >${CRASHDIR}/configs/mac - : >${CRASHDIR}/configs/ip_filter - echo ----------------------------------------------- - echo -e "\033[31m设备列表已清空!\033[0m" - macfilter - ;; - *) - errornum - ;; - esac + get_devinfo() { + dev_ip=$(cat $dhcpdir | grep " $dev " | awk '{print $3}') && [ -z "$dev_ip" ] && dev_ip=$dev + dev_mac=$(cat $dhcpdir | grep " $dev " | awk '{print $2}') && [ -z "$dev_mac" ] && dev_mac=$dev + dev_name=$(cat $dhcpdir | grep " $dev " | awk '{print $4}') && [ -z "$dev_name" ] && dev_name='未知设备' + } + add_mac() { + echo "-----------------------------------------------" + echo 已添加的mac地址: + cat ${CRASHDIR}/configs/mac 2>/dev/null + echo "-----------------------------------------------" + echo -e "\033[33m序号 设备IP 设备mac地址 设备名称\033[32m" + cat $dhcpdir | awk '{print " "NR" "$3,$2,$4}' + echo -e "\033[0m-----------------------------------------------" + echo -e "手动输入mac地址时仅支持\033[32mxx:xx:xx:xx:xx:xx\033[0m的形式" + echo -e " 0 或回车 结束添加" + echo "-----------------------------------------------" + read -p "请输入对应序号或直接输入mac地址 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ -n "$(echo $num | grep -aE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$')" ]; then + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$num")" ]; then + echo $num | grep -oE '^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$' >>${CRASHDIR}/configs/mac + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" + fi + add_mac + elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then + macadd=$(cat $dhcpdir | awk '{print $2}' | sed -n "$num"p) + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$macadd")" ]; then + echo $macadd >>${CRASHDIR}/configs/mac + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的设备,请勿重复添加!\033[0m" + fi + add_mac + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + add_mac + fi + } + add_ip() { + echo "-----------------------------------------------" + echo "已添加的IP地址(段):" + cat ${CRASHDIR}/configs/ip_filter 2>/dev/null + echo "-----------------------------------------------" + echo -e "\033[33m序号 设备IP 设备名称\033[32m" + cat $dhcpdir | awk '{print " "NR" "$3,$4}' + echo -e "\033[0m-----------------------------------------------" + echo -e "手动输入时仅支持\033[32m 192.168.1.0/24\033[0m 或 \033[32m192.168.1.0\033[0m 的形式" + echo -e "不支持ipv6地址过滤,如有需求请使用mac地址过滤" + echo -e " 0 或回车 结束添加" + echo "-----------------------------------------------" + read -p "请输入对应序号或直接输入IP地址段 > " num + if [ -z "$num" -o "$num" = 0 ]; then + i= + elif [ -n "$(echo $num | grep -aE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$')" ]; then + if [ -z "$(cat ${CRASHDIR}/configs/ip_filter | grep -E "$num")" ]; then + echo $num | grep -oE '^((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(/(3[0-2]|[12]?[0-9]))?$' >>${CRASHDIR}/configs/ip_filter + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" + fi + add_ip + elif [ $num -le $(cat $dhcpdir 2>/dev/null | awk 'END{print NR}') ]; then + ipadd=$(cat $dhcpdir | awk '{print $3}' | sed -n "$num"p) + if [ -z "$(cat ${CRASHDIR}/configs/mac | grep -E "$ipadd")" ]; then + echo $ipadd >>${CRASHDIR}/configs/ip_filter + else + echo "-----------------------------------------------" + echo -e "\033[31m已添加的地址,请勿重复添加!\033[0m" + fi + add_ip + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + add_ip + fi + } + del_all() { + echo "-----------------------------------------------" + if [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ]; then + echo -e "\033[31m列表中没有需要移除的设备!\033[0m" + sleep 1 + else + echo -e "请选择需要移除的设备:\033[36m" + echo -e "\033[33m 设备IP 设备mac地址 设备名称\033[0m" + i=1 + for dev in $(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null); do + get_devinfo + echo -e " $i \033[32m$dev_ip \033[36m$dev_mac \033[32m$dev_name\033[0m" + i=$((i + 1)) + done + echo "-----------------------------------------------" + echo -e "\033[0m 0 或回车 结束删除" + read -p "请输入需要移除的设备的对应序号 > " num + mac_filter_rows=$(cat ${CRASHDIR}/configs/mac 2>/dev/null | wc -l) + ip_filter_rows=$(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null | wc -l) + if [ -z "$num" ] || [ "$num" -le 0 ]; then + n= + elif [ $num -le $mac_filter_rows ]; then + sed -i "${num}d" ${CRASHDIR}/configs/mac + echo "-----------------------------------------------" + echo -e "\033[32m对应设备已移除!\033[0m" + del_all + elif [ $num -le $((mac_filter_rows + ip_filter_rows)) ]; then + num=$((num - mac_filter_rows)) + sed -i "${num}d" ${CRASHDIR}/configs/ip_filter + echo "-----------------------------------------------" + echo -e "\033[32m对应设备已移除!\033[0m" + del_all + else + echo "-----------------------------------------------" + echo -e "\033[31m输入有误,请重新输入!\033[0m" + del_all + fi + fi + } + echo "-----------------------------------------------" + [ -z "$dhcpdir" ] && [ -f /var/lib/dhcp/dhcpd.leases ] && dhcpdir='/var/lib/dhcp/dhcpd.leases' + [ -z "$dhcpdir" ] && [ -f /var/lib/dhcpd/dhcpd.leases ] && dhcpdir='/var/lib/dhcpd/dhcpd.leases' + [ -z "$dhcpdir" ] && [ -f /tmp/dhcp.leases ] && dhcpdir='/tmp/dhcp.leases' + [ -z "$dhcpdir" ] && [ -f /tmp/dnsmasq.leases ] && dhcpdir='/tmp/dnsmasq.leases' + [ -z "$dhcpdir" ] && dhcpdir='/dev/null' + [ -z "$macfilter_type" ] && macfilter_type='黑名单' + if [ "$macfilter_type" = "黑名单" ]; then + macfilter_over='白名单' + macfilter_scrip='不' + else + macfilter_over='黑名单' + macfilter_scrip='' + fi + ###### + echo -e "\033[30;47m请在此添加或移除设备\033[0m" + echo -e "当前过滤方式为:\033[33m$macfilter_type模式\033[0m" + echo -e "仅列表内设备流量\033[36m$macfilter_scrip经过\033[0m内核" + if [ -n "$(cat ${CRASHDIR}/configs/mac)" ]; then + echo "-----------------------------------------------" + echo -e "当前已过滤设备为:\033[36m" + echo -e "\033[33m 设备mac/ip地址 设备名称\033[0m" + for dev in $(cat ${CRASHDIR}/configs/mac 2>/dev/null); do + get_devinfo + echo -e "\033[36m$dev_mac \033[0m$dev_name" + done + for dev in $(cat ${CRASHDIR}/configs/ip_filter 2>/dev/null); do + get_devinfo + echo -e "\033[32m$dev_ip \033[0m$dev_name" + done + echo "-----------------------------------------------" + fi + echo -e " 1 切换为\033[33m$macfilter_over模式\033[0m" + echo -e " 2 \033[32m添加指定设备(mac地址)\033[0m" + echo -e " 3 \033[32m添加指定设备(IP地址/网段)\033[0m" + echo -e " 4 \033[36m移除指定设备\033[0m" + echo -e " 9 \033[31m清空整个列表\033[0m" + echo -e " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + macfilter_type=$macfilter_over + setconfig macfilter_type $macfilter_type + echo "-----------------------------------------------" + echo -e "\033[32m已切换为$macfilter_type模式!\033[0m" + macfilter + ;; + 2) + add_mac + macfilter + ;; + 3) + add_ip + macfilter + ;; + 4) + del_all + macfilter + ;; + 9) + : >${CRASHDIR}/configs/mac + : >${CRASHDIR}/configs/ip_filter + echo "-----------------------------------------------" + echo -e "\033[31m设备列表已清空!\033[0m" + macfilter + ;; + *) + errornum + ;; + esac } setboot() { #启动相关设置 - [ -z "$start_old" ] && start_old=未开启 - [ -z "$start_delay" -o "$start_delay" = 0 ] && delay=未设置 || delay=${start_delay}秒 - [ "$autostart" = "enable" ] && auto_set="\033[33m禁止" || auto_set="\033[32m允许" - [ "${BINDIR}" = "${CRASHDIR}" ] && mini_clash=未开启 || mini_clash=已开启 - [ -z "$network_check" ] && network_check=已开启 - echo ----------------------------------------------- - echo -e "\033[30;47m欢迎使用启动设置菜单:\033[0m" - echo ----------------------------------------------- - echo -e " 1 ${auto_set}\033[0mShellCrash开机启动" - echo -e " 2 使用保守模式: \033[36m$start_old\033[0m ————基于定时任务(每分钟检测)" - echo -e " 3 设置自启延时: \033[36m$delay\033[0m ————用于解决自启后服务受限" - echo -e " 4 启用小闪存模式: \033[36m$mini_clash\033[0m ————用于闪存空间不足的设备" - [ "${BINDIR}" != "${CRASHDIR}" ] && echo -e " 5 设置小闪存目录: \033[36m${BINDIR}\033[0m" - echo -e " 6 自启网络检查: \033[36m$network_check\033[0m ————禁用则跳过自启时网络检查" - echo ----------------------------------------------- - echo -e " 0 \033[0m返回上级菜单\033[0m" - read -p "请输入对应数字 > " num - echo ----------------------------------------------- - case "$num" in - 0) ;; - 1) - if [ "$autostart" = "enable" ]; then - # 禁止自启动:删除各系统的启动项 - [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null - ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 - [rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null - touch ${CRASHDIR}/.dis_startup - autostart=disable - echo -e "\033[33m已禁止ShellCrash开机启动!\033[0m" - elif [ "$autostart" = "disable" ]; then - # 允许自启动:配置各系统的启动项 - [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ] && /etc/init.d/shellcrash enable - ckcmd systemctl && systemctl enable shellcrash.service >/dev/null 2>&1 - rc-status -r >/dev/null 2>&1 && rc-update add shellcrash default >/dev/null - rm -rf ${CRASHDIR}/.dis_startup - autostart=enable - echo -e "\033[32m已设置ShellCrash开机启动!\033[0m" - fi - setboot - ;; - 2) - if [ "$start_old" = "未开启" ] >/dev/null 2>&1; then - echo -e "\033[33m改为使用保守模式启动服务!!\033[0m" - [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null - ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 - start_old=已开启 - setconfig start_old $start_old - ${CRASHDIR}/start.sh stop - else - if grep -qE 'procd|systemd' /proc/1/comm || rc-status -r >/dev/null 2>&1; then - echo -e "\033[32m改为使用系统守护进程启动服务!!\033[0m" - ${CRASHDIR}/start.sh cronset "ShellCrash初始化" - start_old=未开启 - setconfig start_old $start_old - ${CRASHDIR}/start.sh stop + [ -z "$start_old" ] && start_old=未开启 + [ -z "$start_delay" -o "$start_delay" = 0 ] && delay=未设置 || delay=${start_delay}秒 + [ "$autostart" = "enable" ] && auto_set="\033[33m禁止" || auto_set="\033[32m允许" + [ "${BINDIR}" = "${CRASHDIR}" ] && mini_clash=未开启 || mini_clash=已开启 + [ -z "$network_check" ] && network_check=已开启 + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用启动设置菜单:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 ${auto_set}\033[0mShellCrash开机启动" + echo -e " 2 使用保守模式: \033[36m$start_old\033[0m ————基于定时任务(每分钟检测)" + echo -e " 3 设置自启延时: \033[36m$delay\033[0m ————用于解决自启后服务受限" + echo -e " 4 启用小闪存模式: \033[36m$mini_clash\033[0m ————用于闪存空间不足的设备" + [ "${BINDIR}" != "${CRASHDIR}" ] && echo -e " 5 设置小闪存目录: \033[36m${BINDIR}\033[0m" + echo -e " 6 自启网络检查: \033[36m$network_check\033[0m ————禁用则跳过自启时网络检查" + echo "-----------------------------------------------" + echo -e " 0 \033[0m返回上级菜单\033[0m" + read -p "请输入对应数字 > " num + echo "-----------------------------------------------" + case "$num" in + 0) ;; + 1) + if [ "$autostart" = "enable" ]; then + # 禁止自启动:删除各系统的启动项 + [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null + ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 + [rc-status -r >/dev/null 2>&1 && rc-update del shellcrash default >/dev/null + touch ${CRASHDIR}/.dis_startup + autostart=disable + echo -e "\033[33m已禁止ShellCrash开机启动!\033[0m" + elif [ "$autostart" = "disable" ]; then + # 允许自启动:配置各系统的启动项 + [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ] && /etc/init.d/shellcrash enable + ckcmd systemctl && systemctl enable shellcrash.service >/dev/null 2>&1 + rc-status -r >/dev/null 2>&1 && rc-update add shellcrash default >/dev/null + rm -rf ${CRASHDIR}/.dis_startup + autostart=enable + echo -e "\033[32m已设置ShellCrash开机启动!\033[0m" + fi + setboot + ;; + 2) + if [ "$start_old" = "未开启" ] >/dev/null 2>&1; then + echo -e "\033[33m改为使用保守模式启动服务!!\033[0m" + [ -d /etc/rc.d ] && cd /etc/rc.d && rm -rf *shellcrash >/dev/null 2>&1 && cd - >/dev/null + ckcmd systemctl && systemctl disable shellcrash.service >/dev/null 2>&1 + start_old=已开启 + setconfig start_old $start_old + ${CRASHDIR}/start.sh stop + else + if grep -qE 'procd|systemd' /proc/1/comm || rc-status -r >/dev/null 2>&1; then + echo -e "\033[32m改为使用系统守护进程启动服务!!\033[0m" + ${CRASHDIR}/start.sh cronset "ShellCrash初始化" + start_old=未开启 + setconfig start_old $start_old + ${CRASHDIR}/start.sh stop - else - echo -e "\033[31m当前设备不支持以其他模式启动!!\033[0m" - fi - fi - sleep 1 - setboot - ;; - 3) - echo -e "\033[33m如果你的设备启动后可以正常使用,则无需设置!!\033[0m" - echo -e "\033[36m推荐设置为30~120秒之间,请根据设备问题自行试验\033[0m" - read -p "请输入启动延迟时间(0~300秒) > " sec - case "$sec" in - [0-9] | [0-9][0-9] | [0-2][0-9][0-9] | 300) - start_delay=$sec - setconfig start_delay $sec - echo -e "\033[32m设置成功!\033[0m" - ;; - *) - echo -e "\033[31m输入有误,或超过300秒,请重新输入!\033[0m" - ;; - esac - sleep 1 - setboot - ;; - 4) - dir_size=$(df ${CRASHDIR} | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | grep Ava | awk '{print $2}') - if [ "$mini_clash" = "未开启" ]; then - if [ "$dir_size" -gt 20480 ]; then - echo -e "\033[33m您的设备空间充足(>20M),无需开启!\033[0m" - elif [ "$start_old" != '已开启' -a "$(cat /proc/1/comm)" = "systemd" ]; then - echo -e "\033[33m不支持systemd启动模式,请先启用保守模式!\033[0m" - else - [ "$BINDIR" = "$CRASHDIR" ] && BINDIR="$TMPDIR" - echo -e "\033[32m已经启用小闪存功能!\033[0m" - echo -e "如需更换目录,请使用【设置小闪存目录】功能\033[0m" - fi - else - if [ "$dir_size" -lt 8192 ]; then - echo -e "\033[31m您的设备剩余空间不足8M,停用后可能无法正常运行!\033[0m" - read -p "确认停用此功能?(1/0) > " res - [ "$res" = 1 ] && BINDIR="$CRASHDIR" && echo -e "\033[33m已经停用小闪存功能!\033[0m" - else - rm -rf /tmp/ShellCrash - BINDIR="$CRASHDIR" - echo -e "\033[33m已经停用小闪存功能!\033[0m" - fi - fi - setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env - sleep 1 - setboot - ;; - 5) - echo -e "\033[33m如设置到内存,则每次开机后都自动重新下载相关文件\033[0m" - echo -e "\033[33m请确保安装源可用裸连,否则会导致启动失败\033[0m" - echo " 1 使用内存(/tmp)" - echo " 2 选择U盘目录" - echo " 3 自定义目录" - read -p "请输入相应数字 > " num - case "$num" in - 1) - BINDIR="$TMPDIR" - ;; - 2) - set_usb_dir() { - echo "请选择安装目录" - du -hL /mnt | awk '{print " "NR" "$2" "$1}' - read -p "请输入相应数字 > " num - BINDIR=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) - if [ -z "$BINDIR" ]; then - echo "\033[31m输入错误!请重新设置!\033[0m" - set_usb_dir - fi - } - set_usb_dir - ;; - 3) - input_dir() { - read -p "请输入自定义目录 > " BINDIR - if [ ! -d "$BINDIR" ]; then - echo "\033[31m输入错误!请重新设置!\033[0m" - input_dir - fi - } - input_dir - ;; - *) - errornum - ;; - esac - setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env - setboot - ;; - 6) - echo -e "\033[33m如果你的设备启动后可以正常使用,则无需变更设置!!\033[0m" - echo -e "\033[36m禁用时,如果使用了小闪存模式或者rule-set等在线规则,则可能会因无法联网而导致启动失败!\033[0m" - echo -e "\033[32m启用时,会导致部分性能较差或者拨号较慢的设备可能会因查询超时导致启动失败!\033[0m" - read -p "是否切换?(1/0) > " res - [ "$res" = '1' ] && { - if [ "$network_check" = "已禁用" ];then - network_check=已启用 - else - network_check=已禁用 - fi - setconfig network_check $network_check - } - sleep 1 - setboot - ;; - *) - errornum - ;; - esac + else + echo -e "\033[31m当前设备不支持以其他模式启动!!\033[0m" + fi + fi + sleep 1 + setboot + ;; + 3) + echo -e "\033[33m如果你的设备启动后可以正常使用,则无需设置!!\033[0m" + echo -e "\033[36m推荐设置为30~120秒之间,请根据设备问题自行试验\033[0m" + read -p "请输入启动延迟时间(0~300秒) > " sec + case "$sec" in + [0-9] | [0-9][0-9] | [0-2][0-9][0-9] | 300) + start_delay=$sec + setconfig start_delay $sec + echo -e "\033[32m设置成功!\033[0m" + ;; + *) + echo -e "\033[31m输入有误,或超过300秒,请重新输入!\033[0m" + ;; + esac + sleep 1 + setboot + ;; + 4) + dir_size=$(df ${CRASHDIR} | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | grep Ava | awk '{print $2}') + if [ "$mini_clash" = "未开启" ]; then + if [ "$dir_size" -gt 20480 ]; then + echo -e "\033[33m您的设备空间充足(>20M),无需开启!\033[0m" + elif [ "$start_old" != '已开启' -a "$(cat /proc/1/comm)" = "systemd" ]; then + echo -e "\033[33m不支持systemd启动模式,请先启用保守模式!\033[0m" + else + [ "$BINDIR" = "$CRASHDIR" ] && BINDIR="$TMPDIR" + echo -e "\033[32m已经启用小闪存功能!\033[0m" + echo -e "如需更换目录,请使用【设置小闪存目录】功能\033[0m" + fi + else + if [ "$dir_size" -lt 8192 ]; then + echo -e "\033[31m您的设备剩余空间不足8M,停用后可能无法正常运行!\033[0m" + read -p "确认停用此功能?(1/0) > " res + [ "$res" = 1 ] && BINDIR="$CRASHDIR" && echo -e "\033[33m已经停用小闪存功能!\033[0m" + else + rm -rf /tmp/ShellCrash + BINDIR="$CRASHDIR" + echo -e "\033[33m已经停用小闪存功能!\033[0m" + fi + fi + setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env + sleep 1 + setboot + ;; + 5) + echo -e "\033[33m如设置到内存,则每次开机后都自动重新下载相关文件\033[0m" + echo -e "\033[33m请确保安装源可用裸连,否则会导致启动失败\033[0m" + echo " 1 使用内存(/tmp)" + echo " 2 选择U盘目录" + echo " 3 自定义目录" + read -p "请输入相应数字 > " num + case "$num" in + 1) + BINDIR="$TMPDIR" + ;; + 2) + set_usb_dir() { + echo "请选择安装目录" + du -hL /mnt | awk '{print " "NR" "$2" "$1}' + read -p "请输入相应数字 > " num + BINDIR=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p) + if [ -z "$BINDIR" ]; then + echo "\033[31m输入错误!请重新设置!\033[0m" + set_usb_dir + fi + } + set_usb_dir + ;; + 3) + input_dir() { + read -p "请输入自定义目录 > " BINDIR + if [ ! -d "$BINDIR" ]; then + echo "\033[31m输入错误!请重新设置!\033[0m" + input_dir + fi + } + input_dir + ;; + *) + errornum + ;; + esac + setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env + setboot + ;; + 6) + echo -e "\033[33m如果你的设备启动后可以正常使用,则无需变更设置!!\033[0m" + echo -e "\033[36m禁用时,如果使用了小闪存模式或者rule-set等在线规则,则可能会因无法联网而导致启动失败!\033[0m" + echo -e "\033[32m启用时,会导致部分性能较差或者拨号较慢的设备可能会因查询超时导致启动失败!\033[0m" + read -p "是否切换?(1/0) > " res + [ "$res" = '1' ] && { + if [ "$network_check" = "已禁用" ]; then + network_check=已启用 + else + network_check=已禁用 + fi + setconfig network_check $network_check + } + sleep 1 + setboot + ;; + *) + errornum + ;; + esac } set_firewall_area() { #防火墙模式设置 - [ -z "$vm_redir" ] && vm_redir='未开启' - echo ----------------------------------------------- - echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6!" - echo -e "\033[33m如你使用了第三方DNS如smartdns等,请勿启用本机代理或使用shellcrash用户执行!\033[0m" - echo ----------------------------------------------- - echo -e " 1 \033[32m仅劫持局域网流量\033[0m" - echo -e " 2 \033[36m仅劫持本机流量\033[0m" - echo -e " 3 \033[32m劫持局域网+本机流量\033[0m" - echo -e " 4 不配置流量劫持(纯净模式)\033[0m" - #echo -e " 5 \033[33m转发局域网流量到旁路由设备\033[0m" - echo -e " 6 劫持容器/虚拟机流量: \033[36m$vm_redir\033[0m" - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - 0) ;; - [1-4]) - [ $firewall_area -ge 4 ] && { - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - } - [ "$num" = 4 ] && { - redir_mod=纯净模式 - setconfig redir_mod $redir_mod - } - firewall_area=$num - setconfig firewall_area $firewall_area - ;; - 5) - echo ----------------------------------------------- - echo -e "\033[31m注意:\033[0m此功能存在多种风险如无网络基础请勿尝试!" - echo -e "\033[33m说明:\033[0m此功能不启动内核仅配置防火墙转发,且子设备无需额外设置网关DNS" - echo -e "\033[33m说明:\033[0m支持防火墙分流及设备过滤,支持部分定时任务,但不支持ipv6!" - echo -e "\033[31m注意:\033[0m如需代理UDP,请确保旁路由运行了支持UDP代理的模式!" - echo -e "\033[31m注意:\033[0m如使用systemd方式启动,内核依然会空载运行,建议使用保守模式!" - echo ----------------------------------------------- - read -p "请输入旁路由IPV4地址 > " bypass_host - [ -n "$bypass_host" ] && { - firewall_area=$num - setconfig firewall_area $firewall_area - setconfig bypass_host $bypass_host - redir_mod=TCP旁路转发 - setconfig redir_mod $redir_mod - } - ;; - 6) - if [ -n "$vm_ipv4" ]; then - vm_des='当前劫持' - else - vm_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -E 'docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | sed 's/.*inet.//g' | sed 's/ br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ') - vm_des='当前获取到' - fi - echo ----------------------------------------------- - echo -e "$vm_des的容器/虚拟机网段为:\033[32m$vm_ipv4\033[0m" - echo -e "如未包含容器网段,请先运行容器再运行脚本或者手动设置网段" - echo ----------------------------------------------- - echo -e " 1 \033[32m启用劫持并使用默认网段\033[0m" - echo -e " 2 \033[36m启用劫持并自定义网段\033[0m" - echo -e " 3 \033[31m禁用劫持\033[0m" - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case $num in - 1) - if [ -n "$vm_ipv4" ];then - vm_redir=已开启 - else - echo -e "\033[33m请先运行容器再运行脚本或者手动设置网段\033[0m" - fi - ;; - 2) - echo -e "多个网段请用空格连接,可运行容器后使用【ip route】命令查看网段地址" - echo -e "示例:\033[32m10.88.0.0/16 172.17.0.0/16\033[0m" - read -p "请输入自定义网段 > " text - [ -n "$text" ] && vm_ipv4=$text && vm_redir=已开启 - ;; - 3) - vm_redir=未开启 - unset vm_ipv4 - ;; - *) ;; - esac - setconfig vm_redir $vm_redir - setconfig vm_ipv4 "'$vm_ipv4'" - sleep 1 - set_firewall_area - ;; - *) errornum ;; - esac - sleep 1 + [ -z "$vm_redir" ] && vm_redir='未开启' + echo "-----------------------------------------------" + echo -e "\033[31m注意:\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6!" + echo -e "\033[33m如你使用了第三方DNS如smartdns等,请勿启用本机代理或使用shellcrash用户执行!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[32m仅劫持局域网流量\033[0m" + echo -e " 2 \033[36m仅劫持本机流量\033[0m" + echo -e " 3 \033[32m劫持局域网+本机流量\033[0m" + echo -e " 4 不配置流量劫持(纯净模式)\033[0m" + #echo -e " 5 \033[33m转发局域网流量到旁路由设备\033[0m" + echo -e " 6 劫持容器/虚拟机流量: \033[36m$vm_redir\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + [1-4]) + [ $firewall_area -ge 4 ] && { + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + } + [ "$num" = 4 ] && { + redir_mod=纯净模式 + setconfig redir_mod $redir_mod + } + firewall_area=$num + setconfig firewall_area $firewall_area + ;; + 5) + echo "-----------------------------------------------" + echo -e "\033[31m注意:\033[0m此功能存在多种风险如无网络基础请勿尝试!" + echo -e "\033[33m说明:\033[0m此功能不启动内核仅配置防火墙转发,且子设备无需额外设置网关DNS" + echo -e "\033[33m说明:\033[0m支持防火墙分流及设备过滤,支持部分定时任务,但不支持ipv6!" + echo -e "\033[31m注意:\033[0m如需代理UDP,请确保旁路由运行了支持UDP代理的模式!" + echo -e "\033[31m注意:\033[0m如使用systemd方式启动,内核依然会空载运行,建议使用保守模式!" + echo "-----------------------------------------------" + read -p "请输入旁路由IPV4地址 > " bypass_host + [ -n "$bypass_host" ] && { + firewall_area=$num + setconfig firewall_area $firewall_area + setconfig bypass_host $bypass_host + redir_mod=TCP旁路转发 + setconfig redir_mod $redir_mod + } + ;; + 6) + if [ -n "$vm_ipv4" ]; then + vm_des='当前劫持' + else + vm_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -E 'docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | sed 's/.*inet.//g' | sed 's/ br.*$//g' | sed 's/metric.*$//g' | tr '\n' ' ') + vm_des='当前获取到' + fi + echo "-----------------------------------------------" + echo -e "$vm_des的容器/虚拟机网段为:\033[32m$vm_ipv4\033[0m" + echo -e "如未包含容器网段,请先运行容器再运行脚本或者手动设置网段" + echo "-----------------------------------------------" + echo -e " 1 \033[32m启用劫持并使用默认网段\033[0m" + echo -e " 2 \033[36m启用劫持并自定义网段\033[0m" + echo -e " 3 \033[31m禁用劫持\033[0m" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 1) + if [ -n "$vm_ipv4" ]; then + vm_redir=已开启 + else + echo -e "\033[33m请先运行容器再运行脚本或者手动设置网段\033[0m" + fi + ;; + 2) + echo -e "多个网段请用空格连接,可运行容器后使用【ip route】命令查看网段地址" + echo -e "示例:\033[32m10.88.0.0/16 172.17.0.0/16\033[0m" + read -p "请输入自定义网段 > " text + [ -n "$text" ] && vm_ipv4=$text && vm_redir=已开启 + ;; + 3) + vm_redir=未开启 + unset vm_ipv4 + ;; + *) ;; + esac + setconfig vm_redir $vm_redir + setconfig vm_ipv4 "'$vm_ipv4'" + sleep 1 + set_firewall_area + ;; + *) errornum ;; + esac + sleep 1 } set_redir_mod() { #代理模式设置 - set_redir_config() { - setconfig redir_mod $redir_mod - setconfig dns_mod $dns_mod - echo ----------------------------------------------- - echo -e "\033[36m已设为 $redir_mod !!\033[0m" - } - [ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1 - [ -z "$firewall_area" ] && firewall_area=1 - [ -z "$firewall_mod" ] && firewall_mod=未设置 - firewall_area_dsc=$(echo "仅局域网 仅本机 局域网+本机 纯净模式 主-旁转发($bypass_host)" | cut -d' ' -f$firewall_area) - echo ----------------------------------------------- - echo -e "当前代理模式为:\033[47;30m$redir_mod\033[0m;ShellCrash核心为:\033[47;30m $crashcore \033[0m" - echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" - echo ----------------------------------------------- - [ $firewall_area -le 3 ] && { - echo -e " 1 \033[32mRedir模式\033[0m: Redir转发TCP,不转发UDP" - echo -e " 2 \033[36m混合模式\033[0m: Redir转发TCP,Tun转发UDP" - echo -e " 3 \033[32mTproxy模式\033[0m: Tproxy转发TCP&UDP" - echo -e " 4 \033[33mTun模式\033[0m: Tun转发TCP&UDP(占用高不推荐)" - echo ----------------------------------------------- - } - [ "$firewall_area" = 5 ] && { - echo -e " 5 \033[32mTCP旁路转发\033[0m: 仅转发TCP流量至旁路由" - echo -e " 6 \033[36mT&U旁路转发\033[0m: 转发TCP&UDP流量至旁路由" - echo ----------------------------------------------- - } - echo -e " 7 设置劫持范围:\033[47;30m$firewall_area_dsc\033[0m" - echo -e " 8 切换防火墙应用:\033[47;30m$firewall_mod\033[0m" - echo -e " 9 ipv6设置:\033[47;30m$ipv6_redir\033[0m" - echo " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case $num in - 0) ;; - 1) - redir_mod=Redir模式 - set_redir_config - set_redir_mod - ;; - 2) - if [ -n "$sup_tun" ]; then - redir_mod=混合模式 - set_redir_config - else - echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - set_redir_mod - ;; - 3) - if [ "$firewall_mod" = "iptables" ]; then - if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ]; then - read -p "xiaomi设备的QOS服务与本模式冲突,是否禁用相关功能?(1/0) > " res - [ "$res" = '1' ] && { - ${CRASHDIR}/misnap_init.sh tproxyfix - redir_mod=Tproxy模式 - set_redir_config - } - elif grep -qE '^TPROXY$' /proc/net/ip_tables_targets || modprobe xt_TPROXY >/dev/null 2>&1; then - redir_mod=Tproxy模式 - set_redir_config - else - echo -e "\033[31m设备未检测到iptables-mod-tproxy模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - elif [ "$firewall_mod" = "nftables" ]; then - if modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy; then - redir_mod=Tproxy模式 - set_redir_config - else - echo -e "\033[31m设备未检测到nft_tproxy内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - fi - set_redir_mod - ;; - 4) - if [ -n "$sup_tun" ]; then - redir_mod=Tun模式 - set_redir_config - else - echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" - sleep 1 - fi - set_redir_mod - ;; - 5) - redir_mod=TCP旁路转发 - set_redir_config - set_redir_mod - ;; - 6) - redir_mod=T & - U旁路转发 - set_redir_config - set_redir_mod - ;; - 7) - set_firewall_area - set_redir_mod - ;; - 8) - if [ "$firewall_mod" = 'iptables' ]; then - if nft add table inet shellcrash 2>/dev/null; then - firewall_mod=nftables - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - else - echo -e "\033[31m当前设备未安装nftables或者nftables版本过低(<1.0.2),无法切换!\033[0m" - fi - elif [ "$firewall_mod" = 'nftables' ]; then - if ckcmd iptables; then - firewall_mod=iptables - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - else - echo -e "\033[31m当前设备未安装iptables,无法切换!\033[0m" - fi - else - iptables -j REDIRECT -h >/dev/null 2>&1 && firewall_mod=iptables - nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables - if [ -n "$firewall_mod" ]; then - redir_mod=Redir模式 - setconfig redir_mod $redir_mod - setconfig firewall_mod $firewall_mod - else - echo -e "\033[31m检测不到可用的防火墙应用(iptables/nftables),无法切换!\033[0m" - fi - fi - sleep 1 - setconfig firewall_mod $firewall_mod - set_redir_mod - ;; - 9) - setipv6 - set_redir_mod - ;; - *) - errornum - ;; - esac + set_redir_config() { + setconfig redir_mod $redir_mod + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $redir_mod !!\033[0m" + } + [ -n "$(ls /dev/net/tun 2>/dev/null)" ] || ip tuntap >/dev/null 2>&1 && sup_tun=1 + [ -z "$firewall_area" ] && firewall_area=1 + [ -z "$firewall_mod" ] && firewall_mod=未设置 + firewall_area_dsc=$(echo "仅局域网 仅本机 局域网+本机 纯净模式 主-旁转发($bypass_host)" | cut -d' ' -f$firewall_area) + echo "-----------------------------------------------" + echo -e "当前代理模式为:\033[47;30m$redir_mod\033[0m;ShellCrash核心为:\033[47;30m $crashcore \033[0m" + echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" + echo "-----------------------------------------------" + [ $firewall_area -le 3 ] && { + echo -e " 1 \033[32mRedir模式\033[0m: Redir转发TCP,不转发UDP" + echo -e " 2 \033[36m混合模式\033[0m: Redir转发TCP,Tun转发UDP" + echo -e " 3 \033[32mTproxy模式\033[0m: Tproxy转发TCP&UDP" + echo -e " 4 \033[33mTun模式\033[0m: Tun转发TCP&UDP(占用高不推荐)" + echo "-----------------------------------------------" + } + [ "$firewall_area" = 5 ] && { + echo -e " 5 \033[32mTCP旁路转发\033[0m: 仅转发TCP流量至旁路由" + echo -e " 6 \033[36mT&U旁路转发\033[0m: 转发TCP&UDP流量至旁路由" + echo "-----------------------------------------------" + } + echo -e " 7 设置劫持范围:\033[47;30m$firewall_area_dsc\033[0m" + echo -e " 8 切换防火墙应用:\033[47;30m$firewall_mod\033[0m" + echo -e " 9 ipv6设置:\033[47;30m$ipv6_redir\033[0m" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + redir_mod=Redir模式 + set_redir_config + set_redir_mod + ;; + 2) + if [ -n "$sup_tun" ]; then + redir_mod=混合模式 + set_redir_config + else + echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + set_redir_mod + ;; + 3) + if [ "$firewall_mod" = "iptables" ]; then + if [ -f /etc/init.d/qca-nss-ecm -a "$systype" = "mi_snapshot" ]; then + read -p "xiaomi设备的QOS服务与本模式冲突,是否禁用相关功能?(1/0) > " res + [ "$res" = '1' ] && { + ${CRASHDIR}/misnap_init.sh tproxyfix + redir_mod=Tproxy模式 + set_redir_config + } + elif grep -qE '^TPROXY$' /proc/net/ip_tables_targets || modprobe xt_TPROXY >/dev/null 2>&1; then + redir_mod=Tproxy模式 + set_redir_config + else + echo -e "\033[31m设备未检测到iptables-mod-tproxy模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + elif [ "$firewall_mod" = "nftables" ]; then + if modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy; then + redir_mod=Tproxy模式 + set_redir_config + else + echo -e "\033[31m设备未检测到nft_tproxy内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + fi + set_redir_mod + ;; + 4) + if [ -n "$sup_tun" ]; then + redir_mod=Tun模式 + set_redir_config + else + echo -e "\033[31m设备未检测到Tun内核模块,请尝试其他模式或者安装相关依赖!\033[0m" + sleep 1 + fi + set_redir_mod + ;; + 5) + redir_mod=TCP旁路转发 + set_redir_config + set_redir_mod + ;; + 6) + redir_mod=T & + U旁路转发 + set_redir_config + set_redir_mod + ;; + 7) + set_firewall_area + set_redir_mod + ;; + 8) + if [ "$firewall_mod" = 'iptables' ]; then + if nft add table inet shellcrash 2>/dev/null; then + firewall_mod=nftables + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + else + echo -e "\033[31m当前设备未安装nftables或者nftables版本过低(<1.0.2),无法切换!\033[0m" + fi + elif [ "$firewall_mod" = 'nftables' ]; then + if ckcmd iptables; then + firewall_mod=iptables + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + else + echo -e "\033[31m当前设备未安装iptables,无法切换!\033[0m" + fi + else + iptables -j REDIRECT -h >/dev/null 2>&1 && firewall_mod=iptables + nft add table inet shellcrash 2>/dev/null && firewall_mod=nftables + if [ -n "$firewall_mod" ]; then + redir_mod=Redir模式 + setconfig redir_mod $redir_mod + setconfig firewall_mod $firewall_mod + else + echo -e "\033[31m检测不到可用的防火墙应用(iptables/nftables),无法切换!\033[0m" + fi + fi + sleep 1 + setconfig firewall_mod $firewall_mod + set_redir_mod + ;; + 9) + setipv6 + set_redir_mod + ;; + *) + errornum + ;; + esac } set_dns_mod() { #DNS模式设置 - echo ----------------------------------------------- - echo -e "当前DNS运行模式为:\033[47;30m $dns_mod \033[0m" - echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" - echo ----------------------------------------------- - echo -e " 1 fake-ip模式: 响应快,\033[33m兼容性较差\033[0m" - echo -e " 不支持CN-IP绕过功能" - echo -e " 2 redir_host模式:\033[33m不安全,易被污染\033[0m" - echo -e " 建议搭配第三方DNS服务使用" - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - echo -e " 3 mix混合模式: \033[32m防污染防泄露,响应快,推荐!\033[0m" - echo -e " cn域名realip其他fakeip分流" - echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" - echo -e " cn域名realip其他dns2proxy分流" - fi - echo -e " 9 \033[36mDNS进阶设置\033[0m" - echo " 0 返回上级菜单" - read -p "请输入对应数字 > " num - case $num in - 0) ;; - 1) - dns_mod=fake-ip - setconfig dns_mod $dns_mod - echo ----------------------------------------------- - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - ;; - 2) - dns_mod=redir_host - setconfig dns_mod $dns_mod - echo ----------------------------------------------- - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - ;; - 3) - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - dns_mod=mix - setconfig dns_mod $dns_mod - echo ----------------------------------------------- - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - else - echo -e "\033[31m当前内核不支持的功能!!!\033[0m" - sleep 1 - fi - ;; - 4) - if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then - dns_mod=route - setconfig dns_mod $dns_mod - echo ----------------------------------------------- - echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" - else - echo -e "\033[31m当前内核不支持的功能!!!\033[0m" - sleep 1 - fi - ;; - 9) - setdns - set_dns_mod - ;; - *) - errornum - ;; - esac + echo "-----------------------------------------------" + echo -e "当前DNS运行模式为:\033[47;30m $dns_mod \033[0m" + echo -e "\033[33m切换模式后需要手动重启服务以生效!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 fake-ip模式: 响应快,\033[33m兼容性较差\033[0m" + echo -e " 不支持CN-IP绕过功能" + echo -e " 2 redir_host模式:\033[33m不安全,易被污染\033[0m" + echo -e " 建议搭配第三方DNS服务使用" + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + echo -e " 3 mix混合模式: \033[32m防污染防泄露,响应快,推荐!\033[0m" + echo -e " cn域名realip其他fakeip分流" + echo -e " 4 route模式: \033[32m防污染防泄露,全真实IP\033[0m" + echo -e " cn域名realip其他dns2proxy分流" + fi + echo -e " 9 \033[36mDNS进阶设置\033[0m" + echo " 0 返回上级菜单" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 1) + dns_mod=fake-ip + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + ;; + 2) + dns_mod=redir_host + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + ;; + 3) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=mix + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + ;; + 4) + if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then + dns_mod=route + setconfig dns_mod $dns_mod + echo "-----------------------------------------------" + echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m" + else + echo -e "\033[31m当前内核不支持的功能!!!\033[0m" + sleep 1 + fi + ;; + 9) + setdns + set_dns_mod + ;; + *) + errornum + ;; + esac } fake_ip_filter() { - echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m" - echo -e "\033[31m脚本已经内置了大量地址,你只需要添加出现问题的地址!\033[0m" - echo -e "\033[36m示例:a.b.com" - echo -e "示例:*.b.com" - echo -e "示例:*.*.b.com\033[0m" - echo ----------------------------------------------- - if [ -s ${CRASHDIR}/configs/fake_ip_filter ]; then - echo -e "\033[33m已添加Fake-ip过滤地址:\033[0m" - cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}' - else - echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m" - fi - echo ----------------------------------------------- - echo -e "\033[32m输入数字直接移除对应地址,输入地址直接添加!\033[0m" - read -p "请输入数字或地址 > " input - case $input in - 0) ;; - '') ;; - *) - if [ $input -ge 1 ] 2>/dev/null;then - sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null - echo -e "\033[32m移除成功!\033[0m" - else - echo -e "你输入的地址是:\033[32m$input\033[0m" - read -p "确认添加?(1/0) > " res - [ "$res" = 1 ] && echo $input >>${CRASHDIR}/configs/fake_ip_filter - fi - sleep 1 - fake_ip_filter - ;; - esac + echo -e "\033[32m用于解决Fake-ip模式下部分地址或应用无法连接的问题\033[0m" + echo -e "\033[31m脚本已经内置了大量地址,你只需要添加出现问题的地址!\033[0m" + echo -e "\033[36m示例:a.b.com" + echo -e "示例:*.b.com" + echo -e "示例:*.*.b.com\033[0m" + echo "-----------------------------------------------" + if [ -s ${CRASHDIR}/configs/fake_ip_filter ]; then + echo -e "\033[33m已添加Fake-ip过滤地址:\033[0m" + cat ${CRASHDIR}/configs/fake_ip_filter | awk '{print NR" "$1}' + else + echo -e "\033[33m你还未添加Fake-ip过滤地址\033[0m" + fi + echo "-----------------------------------------------" + echo -e "\033[32m输入数字直接移除对应地址,输入地址直接添加!\033[0m" + read -p "请输入数字或地址 > " input + case "$input" in + 0) ;; + '') ;; + *) + if [ $input -ge 1 ] 2>/dev/null; then + sed -i "${input}d" ${CRASHDIR}/configs/fake_ip_filter 2>/dev/null + echo -e "\033[32m移除成功!\033[0m" + else + echo -e "你输入的地址是:\033[32m$input\033[0m" + read -p "确认添加?(1/0) > " res + [ "$res" = 1 ] && echo $input >>${CRASHDIR}/configs/fake_ip_filter + fi + sleep 1 + fake_ip_filter + ;; + esac } normal_set() { #基础设置 - #获取设置默认显示 - [ -z "$skip_cert" ] && skip_cert=已开启 - [ -z "$common_ports" ] && common_ports=已开启 - [ -z "$dns_mod" ] && dns_mod=fake-ip - [ -z "$dns_over" ] && dns_over=已开启 - [ -z "$cn_ip_route" ] && cn_ip_route=未开启 - [ -z "$local_proxy" ] && local_proxy=未开启 - [ -z "$quic_rj" ] && quic_rj=未开启 - [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ] && mac_return=未开启 || mac_return=已启用 - # - echo ----------------------------------------------- - echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" - echo ----------------------------------------------- - echo -e " 1 切换防火墙运行模式: \033[36m$redir_mod\033[0m" - [ "$disoverride" != "1" ] && { - echo -e " 2 切换DNS运行模式: \033[36m$dns_mod\033[0m" - echo -e " 3 跳过本地证书验证: \033[36m$skip_cert\033[0m ————解决节点证书验证错误" - } - echo -e " 4 只代理常用端口: \033[36m$common_ports\033[0m ————用于过滤P2P流量" - echo -e " 5 过滤局域网设备: \033[36m$mac_return\033[0m ————使用黑/白名单进行过滤" - echo -e " 7 屏蔽QUIC流量: \033[36m$quic_rj\033[0m ————优化视频性能" - [ "$disoverride" != "1" ] && { - [ "$dns_mod" != "fake-ip" ] && - echo -e " 8 CN_IP绕过内核: \033[36m$cn_ip_route\033[0m ————优化性能,不兼容Fake-ip" - [ "$dns_mod" != "redir_host" ] && - echo -e " 9 管理Fake-ip过滤列表" - } - echo ----------------------------------------------- - echo -e " 0 返回上级菜单 \033[0m" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= - elif [ "$num" = 1 ]; then - if [ "$USER" != "root" -a "$USER" != "admin" ]; then - echo ----------------------------------------------- - read -p "非root用户可能无法正确配置其他模式!依然尝试吗?(1/0) > " res - [ "$res" = 1 ] && set_redir_mod - else - set_redir_mod - fi - normal_set - - elif [ "$num" = 2 ]; then - set_dns_mod - sleep 1 - normal_set - - elif [ "$num" = 3 ]; then - echo ----------------------------------------------- - if [ "$skip_cert" = "未开启" ] >/dev/null 2>&1; then - echo -e "\033[33m已设为开启跳过本地证书验证!!\033[0m" - skip_cert=已开启 - else - echo -e "\033[33m已设为禁止跳过本地证书验证!!\033[0m" - skip_cert=未开启 - fi - setconfig skip_cert $skip_cert - normal_set - - elif [ "$num" = 4 ]; then - set_common_ports() { - if [ "$common_ports" = "未开启" ]; then - echo -e "\033[33m当前代理端口为:【$multiport】\033[0m" - echo -e "\033[31m注意,fake-ip模式下,非常用端口的域名连接将不受影响!!\033[0m" - read -p "是否修改默认端口?(1/0) > " res - [ "$res" = "1" ] && { - read -p "请输入自定义端口,注意用小写逗号分隔 > " text - [ -n "$text" ] && setconfig multiport $text && echo -e "\033[33m已设为代理【$multiport】端口!!\033[0m" - } - common_ports=已开启 - sleep 1 - else - echo -e "\033[33m已设为代理全部端口!!\033[0m" - common_ports=未开启 - fi - setconfig common_ports $common_ports - } - echo ----------------------------------------------- - if [ -n "$(pidof CrashCore)" ]; then - read -p "切换时将停止服务,是否继续?(1/0) > " res - [ "$res" = 1 ] && ${CRASHDIR}/start.sh stop && set_common_ports - else - set_common_ports - fi - normal_set - - elif [ "$num" = 5 ]; then - checkcfg_mac=$(cat ${CRASHDIR}/configs/mac) - macfilter - if [ -n "$PID" ]; then - checkcfg_mac_new=$(cat ${CRASHDIR}/configs/mac) - [ "$checkcfg_mac" != "$checkcfg_mac_new" ] && checkrestart - fi - normal_set - - elif [ "$num" = 7 ]; then - echo ----------------------------------------------- - if [ -n "$(echo "$redir_mod" | grep -oE '混合|Tproxy|Tun')" ]; then - if [ "$quic_rj" = "未开启" ]; then - echo -e "\033[33m已禁止QUIC流量通过ShellCrash内核!!\033[0m" - quic_rj=已启用 - else - echo -e "\033[33m已取消禁止QUIC协议流量!!\033[0m" - quic_rj=未开启 - fi - setconfig quic_rj $quic_rj - else - echo -e "\033[33m当前模式默认不会代理UDP流量,无需设置!!\033[0m" - fi - sleep 1 - normal_set - - elif [ "$num" = 8 ]; then - if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = 'nftables' ]; then - if [ "$cn_ip_route" = "未开启" ]; then - echo -e "\033[32m已开启CN_IP绕过内核功能!!\033[0m" - echo -e "\033[31m注意!!!此功能会导致全局模式及一切CN相关规则失效!!!\033[0m" - cn_ip_route=已开启 - sleep 2 - else - echo -e "\033[33m已禁用CN_IP绕过内核功能!!\033[0m" - cn_ip_route=未开启 - fi - setconfig cn_ip_route $cn_ip_route - else - echo -e "\033[31m当前设备缺少ipset模块或未使用nftables模式,无法启用绕过功能!!\033[0m" - sleep 1 - fi - normal_set - - elif [ "$num" = 9 ]; then - echo ----------------------------------------------- - fake_ip_filter - normal_set - - else - errornum - fi + #获取设置默认显示 + [ -z "$skip_cert" ] && skip_cert=已开启 + [ -z "$common_ports" ] && common_ports=已开启 + [ -z "$dns_mod" ] && dns_mod=fake-ip + [ -z "$dns_over" ] && dns_over=已开启 + [ -z "$cn_ip_route" ] && cn_ip_route=未开启 + [ -z "$local_proxy" ] && local_proxy=未开启 + [ -z "$quic_rj" ] && quic_rj=未开启 + [ -z "$(cat ${CRASHDIR}/configs/mac ${CRASHDIR}/configs/ip_filter 2>/dev/null)" ] && mac_return=未开启 || mac_return=已启用 + # + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用功能设置菜单:\033[0m" + echo "-----------------------------------------------" + echo -e " 1 切换防火墙运行模式: \033[36m$redir_mod\033[0m" + [ "$disoverride" != "1" ] && { + echo -e " 2 切换DNS运行模式: \033[36m$dns_mod\033[0m" + echo -e " 3 跳过本地证书验证: \033[36m$skip_cert\033[0m ————解决节点证书验证错误" + } + echo -e " 4 只代理常用端口: \033[36m$common_ports\033[0m ————用于过滤P2P流量" + echo -e " 5 过滤局域网设备: \033[36m$mac_return\033[0m ————使用黑/白名单进行过滤" + echo -e " 7 屏蔽QUIC流量: \033[36m$quic_rj\033[0m ————优化视频性能" + [ "$disoverride" != "1" ] && { + [ "$dns_mod" != "fake-ip" ] && + echo -e " 8 CN_IP绕过内核: \033[36m$cn_ip_route\033[0m ————优化性能,不兼容Fake-ip" + [ "$dns_mod" != "redir_host" ] && + echo -e " 9 管理Fake-ip过滤列表" + } + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + i= + ;; + 1) + if [ "$USER" != "root" -a "$USER" != "admin" ]; then + echo "-----------------------------------------------" + read -p "非root用户可能无法正确配置其他模式!依然尝试吗?(1/0) > " res + [ "$res" = 1 ] && set_redir_mod + else + set_redir_mod + fi + normal_set + ;; + 2) + set_dns_mod + sleep 1 + normal_set + ;; + 3) + echo "-----------------------------------------------" + if [ "$skip_cert" = "未开启" ] >/dev/null 2>&1; then + echo -e "\033[33m已设为开启跳过本地证书验证!!\033[0m" + skip_cert=已开启 + else + echo -e "\033[33m已设为禁止跳过本地证书验证!!\033[0m" + skip_cert=未开启 + fi + setconfig skip_cert $skip_cert + normal_set + ;; + 4) + set_common_ports() { + if [ "$common_ports" = "未开启" ]; then + echo -e "\033[33m当前代理端口为:【$multiport】\033[0m" + echo -e "\033[31m注意,fake-ip模式下,非常用端口的域名连接将不受影响!!\033[0m" + read -p "是否修改默认端口?(1/0) > " res + [ "$res" = "1" ] && { + read -p "请输入自定义端口,注意用小写逗号分隔 > " text + [ -n "$text" ] && setconfig multiport $text && echo -e "\033[33m已设为代理【$multiport】端口!!\033[0m" + } + common_ports=已开启 + sleep 1 + else + echo -e "\033[33m已设为代理全部端口!!\033[0m" + common_ports=未开启 + fi + setconfig common_ports $common_ports + } + echo "-----------------------------------------------" + if [ -n "$(pidof CrashCore)" ]; then + read -p "切换时将停止服务,是否继续?(1/0) > " res + [ "$res" = 1 ] && ${CRASHDIR}/start.sh stop && set_common_ports + else + set_common_ports + fi + normal_set + ;; + 5) + checkcfg_mac=$(cat ${CRASHDIR}/configs/mac) + macfilter + if [ -n "$PID" ]; then + checkcfg_mac_new=$(cat ${CRASHDIR}/configs/mac) + [ "$checkcfg_mac" != "$checkcfg_mac_new" ] && checkrestart + fi + normal_set + ;; + 7) + echo "-----------------------------------------------" + if [ -n "$(echo "$redir_mod" | grep -oE '混合|Tproxy|Tun')" ]; then + if [ "$quic_rj" = "未开启" ]; then + echo -e "\033[33m已禁止QUIC流量通过ShellCrash内核!!\033[0m" + quic_rj=已启用 + else + echo -e "\033[33m已取消禁止QUIC协议流量!!\033[0m" + quic_rj=未开启 + fi + setconfig quic_rj $quic_rj + else + echo -e "\033[33m当前模式默认不会代理UDP流量,无需设置!!\033[0m" + fi + sleep 1 + normal_set + ;; + 8) + if [ -n "$(ipset -v 2>/dev/null)" ] || [ "$firewall_mod" = 'nftables' ]; then + if [ "$cn_ip_route" = "未开启" ]; then + echo -e "\033[32m已开启CN_IP绕过内核功能!!\033[0m" + echo -e "\033[31m注意!!!此功能会导致全局模式及一切CN相关规则失效!!!\033[0m" + cn_ip_route=已开启 + sleep 2 + else + echo -e "\033[33m已禁用CN_IP绕过内核功能!!\033[0m" + cn_ip_route=未开启 + fi + setconfig cn_ip_route $cn_ip_route + else + echo -e "\033[31m当前设备缺少ipset模块或未使用nftables模式,无法启用绕过功能!!\033[0m" + sleep 1 + fi + normal_set + ;; + 9) + echo "-----------------------------------------------" + fake_ip_filter + normal_set + ;; + *) + errornum + ;; + esac } advanced_set() { #进阶设置 - #获取设置默认显示 - [ -z "$proxies_bypass" ] && proxies_bypass=未启用 - [ -z "$start_old" ] && start_old=未开启 - [ -z "$tproxy_mod" ] && tproxy_mod=未开启 - [ -z "$public_support" ] && public_support=未开启 - [ -z "$sniffer" ] && sniffer=未启用 - [ "$crashcore" = "clashpre" ] && [ "$dns_mod" = "redir_host" ] && sniffer=已启用 - [ "$BINDIR" = "/tmp/ShellCrash" ] && mini_clash=已开启 || mini_clash=未开启 - # - echo ----------------------------------------------- - echo -e "\033[30;47m欢迎使用进阶模式菜单:\033[0m" - echo -e "\033[33m如您并不了解ShellCrash的运行机制,请勿更改本页面功能!\033[0m" - echo ----------------------------------------------- - #echo -e " 2 配置Meta特性" - echo -e " 3 配置公网及局域网防火墙" - [ "$disoverride" != "1" ] && { - echo -e " 4 启用域名嗅探: \033[36m$sniffer\033[0m ————用于流媒体及防DNS污染" - echo -e " 5 自定义\033[32m端口及秘钥\033[0m" - } - echo ----------------------------------------------- - echo -e " 9 \033[31m重置/备份/还原\033[0m脚本设置" - echo -e " 0 返回上级菜单 \033[0m" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - case "$num" in - 0) ;; - 3) - setfirewall - advanced_set - ;; - 4) - echo ----------------------------------------------- - if [ "$sniffer" = "未启用" ]; then - if [ "$crashcore" = "clash" ]; then - rm -rf ${TMPDIR}/CrashCore - rm -rf ${CRASHDIR}/CrashCore - rm -rf ${CRASHDIR}/CrashCore.tar.gz - crashcore=meta - setconfig crashcore $crashcore - echo "已将ShellCrash内核切换为Meta内核!域名嗅探依赖Meta或者高版本clashpre内核!" - fi - sniffer=已启用 - elif [ "$crashcore" = "clashpre" -a "$dns_mod" = "redir_host" ]; then - echo -e "\033[31m使用clashpre内核且开启redir-host模式时无法关闭!\033[0m" - else - sniffer=未启用 - fi - setconfig sniffer $sniffer - echo -e "\033[32m设置成功!\033[0m" - sleep 1 - advanced_set - ;; - 5) - if [ -n "$(pidof CrashCore)" ]; then - echo ----------------------------------------------- - echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" - read -p "是否停止服务?(1/0) > " res - if [ "$res" = "1" ]; then - ${CRASHDIR}/start.sh stop - setport - fi - else - setport - fi - advanced_set - ;; - 9) - echo -e " 1 备份脚本设置" - echo -e " 2 还原脚本设置" - echo -e " 3 重置脚本设置" - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= - elif [ "$num" = 1 ]; then - cp -f $CFG_PATH $CFG_PATH.bak - echo -e "\033[32m脚本设置已备份!\033[0m" - elif [ "$num" = 2 ]; then - if [ -f "$CFG_PATH.bak" ]; then - mv -f $CFG_PATH $CFG_PATH.bak2 - mv -f $CFG_PATH.bak $CFG_PATH - mv -f $CFG_PATH.bak2 $CFG_PATH.bak - echo -e "\033[32m脚本设置已还原!(被覆盖的配置已备份!)\033[0m" - else - echo -e "\033[31m找不到备份文件,请先备份脚本设置!\033[0m" - fi - elif [ "$num" = 3 ]; then - mv -f $CFG_PATH $CFG_PATH.bak - . ${CRASHDIR}/init.sh >/dev/null - echo -e "\033[32m脚本设置已重置!(旧文件已备份!)\033[0m" - fi - echo -e "\033[33m请重新启动脚本!\033[0m" - exit 0 - ;; - *) errornum ;; - esac + #获取设置默认显示 + [ -z "$proxies_bypass" ] && proxies_bypass=未启用 + [ -z "$start_old" ] && start_old=未开启 + [ -z "$tproxy_mod" ] && tproxy_mod=未开启 + [ -z "$public_support" ] && public_support=未开启 + [ -z "$sniffer" ] && sniffer=未启用 + [ "$crashcore" = "clashpre" ] && [ "$dns_mod" = "redir_host" ] && sniffer=已启用 + [ "$BINDIR" = "/tmp/ShellCrash" ] && mini_clash=已开启 || mini_clash=未开启 + # + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用进阶模式菜单:\033[0m" + echo -e "\033[33m如您并不了解ShellCrash的运行机制,请勿更改本页面功能!\033[0m" + echo "-----------------------------------------------" + #echo -e " 2 配置Meta特性" + echo -e " 3 配置公网及局域网防火墙" + [ "$disoverride" != "1" ] && { + echo -e " 4 启用域名嗅探: \033[36m$sniffer\033[0m ————用于流媒体及防DNS污染" + echo -e " 5 自定义\033[32m端口及秘钥\033[0m" + } + echo "-----------------------------------------------" + echo -e " 9 \033[31m重置/备份/还原\033[0m脚本设置" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) ;; + 3) + setfirewall + advanced_set + ;; + 4) + echo "-----------------------------------------------" + if [ "$sniffer" = "未启用" ]; then + if [ "$crashcore" = "clash" ]; then + rm -rf ${TMPDIR}/CrashCore + rm -rf ${CRASHDIR}/CrashCore + rm -rf ${CRASHDIR}/CrashCore.tar.gz + crashcore=meta + setconfig crashcore $crashcore + echo "已将ShellCrash内核切换为Meta内核!域名嗅探依赖Meta或者高版本clashpre内核!" + fi + sniffer=已启用 + elif [ "$crashcore" = "clashpre" -a "$dns_mod" = "redir_host" ]; then + echo -e "\033[31m使用clashpre内核且开启redir-host模式时无法关闭!\033[0m" + else + sniffer=未启用 + fi + setconfig sniffer $sniffer + echo -e "\033[32m设置成功!\033[0m" + sleep 1 + advanced_set + ;; + 5) + if [ -n "$(pidof CrashCore)" ]; then + echo "-----------------------------------------------" + echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" + read -p "是否停止服务?(1/0) > " res + if [ "$res" = "1" ]; then + ${CRASHDIR}/start.sh stop + setport + fi + else + setport + fi + advanced_set + ;; + 9) + echo -e " 1 备份脚本设置" + echo -e " 2 还原脚本设置" + echo -e " 3 重置脚本设置" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + errornum + elif [ "$num" = 0 ]; then + i= + elif [ "$num" = 1 ]; then + cp -f $CFG_PATH $CFG_PATH.bak + echo -e "\033[32m脚本设置已备份!\033[0m" + elif [ "$num" = 2 ]; then + if [ -f "$CFG_PATH.bak" ]; then + mv -f $CFG_PATH $CFG_PATH.bak2 + mv -f $CFG_PATH.bak $CFG_PATH + mv -f $CFG_PATH.bak2 $CFG_PATH.bak + echo -e "\033[32m脚本设置已还原!(被覆盖的配置已备份!)\033[0m" + else + echo -e "\033[31m找不到备份文件,请先备份脚本设置!\033[0m" + fi + elif [ "$num" = 3 ]; then + mv -f $CFG_PATH $CFG_PATH.bak + . ${CRASHDIR}/init.sh >/dev/null + echo -e "\033[32m脚本设置已重置!(旧文件已备份!)\033[0m" + fi + echo -e "\033[33m请重新启动脚本!\033[0m" + exit 0 + ;; + *) errornum ;; + esac } #工具脚本 autoSSH() { - echo ----------------------------------------------- - echo -e "\033[33m本功能使用软件命令进行固化不保证100%成功!\033[0m" - echo -e "\033[33m如有问题请加群反馈:\033[36;4mhttps://t.me/ShellClash\033[0m" - read -p "请输入需要还原的SSH密码(不影响当前密码,回车可跳过) > " mi_autoSSH_pwd - mi_autoSSH=已配置 - cp -f /etc/dropbear/dropbear_rsa_host_key ${CRASHDIR}/configs/dropbear_rsa_host_key 2>/dev/null - cp -f /etc/dropbear/authorized_keys ${CRASHDIR}/configs/authorized_keys 2>/dev/null - ckcmd nvram && { - nvram set ssh_en=1 - nvram set telnet_en=1 - nvram set uart_en=1 - nvram set boot_wait=on - nvram commit - } - echo -e "\033[32m设置成功!\033[0m" - setconfig mi_autoSSH $mi_autoSSH - setconfig mi_autoSSH_pwd $mi_autoSSH_pwd - sleep 1 + echo "-----------------------------------------------" + echo -e "\033[33m本功能使用软件命令进行固化不保证100%成功!\033[0m" + echo -e "\033[33m如有问题请加群反馈:\033[36;4mhttps://t.me/ShellClash\033[0m" + read -p "请输入需要还原的SSH密码(不影响当前密码,回车可跳过) > " mi_autoSSH_pwd + mi_autoSSH=已配置 + cp -f /etc/dropbear/dropbear_rsa_host_key ${CRASHDIR}/configs/dropbear_rsa_host_key 2>/dev/null + cp -f /etc/dropbear/authorized_keys ${CRASHDIR}/configs/authorized_keys 2>/dev/null + ckcmd nvram && { + nvram set ssh_en=1 + nvram set telnet_en=1 + nvram set uart_en=1 + nvram set boot_wait=on + nvram commit + } + echo -e "\033[32m设置成功!\033[0m" + setconfig mi_autoSSH $mi_autoSSH + setconfig mi_autoSSH_pwd $mi_autoSSH_pwd + sleep 1 } uninstall() { - read -p "确认卸载ShellCrash?(警告:该操作不可逆!)[1/0] > " res - if [ "$res" = '1' ]; then - #停止服务 - ${CRASHDIR}/start.sh stop 2>/dev/null - ${CRASHDIR}/start.sh cronset "clash服务" 2>/dev/null - ${CRASHDIR}/start.sh cronset "订阅链接" 2>/dev/null - ${CRASHDIR}/start.sh cronset "ShellCrash初始化" 2>/dev/null - ${CRASHDIR}/start.sh cronset "task.sh" 2>/dev/null - #移除安装目录 - if [ -n "${CRASHDIR}" ] && [ "${CRASHDIR}" != '/' ];then - read -p "是否保留脚本配置及订阅文件?[1/0] > " res - if [ "$res" = '1' ]; then - mv -f ${CRASHDIR}/configs /tmp/ShellCrash/configs_bak - mv -f ${CRASHDIR}/yamls /tmp/ShellCrash/yamls_bak - mv -f ${CRASHDIR}/jsons /tmp/ShellCrash/jsons_bak - rm -rf ${CRASHDIR}/* - mv -f /tmp/ShellCrash/configs_bak "${CRASHDIR}/configs" - mv -f /tmp/ShellCrash/yamls_bak "${CRASHDIR}/yamls" - mv -f /tmp/ShellCrash/jsons_bak "${CRASHDIR}/jsons" - else - rm -rf ${CRASHDIR} - fi - else - echo -e "\033[31m环境变量配置有误,请尝试手动移除安装目录!\033[0m" - sleep 1 - fi - #移除其他内容 - [ -w ~/.bashrc ] && profile=~/.bashrc - [ -w /etc/profile ] && profile=/etc/profile - sed -i "/alias $my_alias=*/"d $profile - sed -i '/alias crash=*/'d $profile - sed -i '/export CRASHDIR=*/'d $profile - sed -i '/export crashdir=*/'d $profile - [ -w ~/.zshrc ] && { - sed -i "/alias $my_alias=*/"d ~/.zshrc - sed -i '/export CRASHDIR=*/'d ~/.zshrc - } - sed -i '/all_proxy/'d $profile - sed -i '/ALL_PROXY/'d $profile - sed -i "/启用外网访问SSH服务/d" /etc/firewall.user 2>/dev/null - sed -i '/ShellCrash初始化/'d /etc/storage/started_script.sh 2>/dev/null - sed -i '/ShellCrash初始化/'d /jffs/.asusrouter 2>/dev/null - [ "$BINDIR" != "$CRASHDIR" ] && rm -rf ${BINDIR} - rm -rf /etc/init.d/shellcrash - rm -rf /etc/systemd/system/shellcrash.service - rm -rf /usr/lib/systemd/system/shellcrash.service - rm -rf /www/clash - rm -rf /tmp/ShellCrash - rm -rf /usr/bin/crash - sed -i '/0:7890/d' /etc/passwd - userdel -r shellcrash 2>/dev/null - nvram set script_usbmount="" 2>/dev/null - nvram commit 2>/dev/null - uci delete firewall.ShellCrash 2>/dev/null - uci commit firewall 2>/dev/null - echo ----------------------------------------------- - echo -e "\033[36m已卸载ShellCrash相关文件!有缘再会!\033[0m" - echo -e "\033[33m请手动关闭当前窗口以重置环境变量!\033[0m" - echo ----------------------------------------------- - exit - else - echo -e "\033[31m操作已取消!\033[0m" - fi + read -p "确认卸载ShellCrash?(警告:该操作不可逆!)[1/0] > " res + if [ "$res" = '1' ]; then + #停止服务 + ${CRASHDIR}/start.sh stop 2>/dev/null + ${CRASHDIR}/start.sh cronset "clash服务" 2>/dev/null + ${CRASHDIR}/start.sh cronset "订阅链接" 2>/dev/null + ${CRASHDIR}/start.sh cronset "ShellCrash初始化" 2>/dev/null + ${CRASHDIR}/start.sh cronset "task.sh" 2>/dev/null + #移除安装目录 + if [ -n "${CRASHDIR}" ] && [ "${CRASHDIR}" != '/' ]; then + read -p "是否保留脚本配置及订阅文件?[1/0] > " res + if [ "$res" = '1' ]; then + mv -f ${CRASHDIR}/configs /tmp/ShellCrash/configs_bak + mv -f ${CRASHDIR}/yamls /tmp/ShellCrash/yamls_bak + mv -f ${CRASHDIR}/jsons /tmp/ShellCrash/jsons_bak + rm -rf ${CRASHDIR}/* + mv -f /tmp/ShellCrash/configs_bak "${CRASHDIR}/configs" + mv -f /tmp/ShellCrash/yamls_bak "${CRASHDIR}/yamls" + mv -f /tmp/ShellCrash/jsons_bak "${CRASHDIR}/jsons" + else + rm -rf ${CRASHDIR} + fi + else + echo -e "\033[31m环境变量配置有误,请尝试手动移除安装目录!\033[0m" + sleep 1 + fi + #移除其他内容 + [ -w ~/.bashrc ] && profile=~/.bashrc + [ -w /etc/profile ] && profile=/etc/profile + sed -i "/alias $my_alias=*/"d $profile + sed -i '/alias crash=*/'d $profile + sed -i '/export CRASHDIR=*/'d $profile + sed -i '/export crashdir=*/'d $profile + [ -w ~/.zshrc ] && { + sed -i "/alias $my_alias=*/"d ~/.zshrc + sed -i '/export CRASHDIR=*/'d ~/.zshrc + } + sed -i '/all_proxy/'d $profile + sed -i '/ALL_PROXY/'d $profile + sed -i "/启用外网访问SSH服务/d" /etc/firewall.user 2>/dev/null + sed -i '/ShellCrash初始化/'d /etc/storage/started_script.sh 2>/dev/null + sed -i '/ShellCrash初始化/'d /jffs/.asusrouter 2>/dev/null + [ "$BINDIR" != "$CRASHDIR" ] && rm -rf ${BINDIR} + rm -rf /etc/init.d/shellcrash + rm -rf /etc/systemd/system/shellcrash.service + rm -rf /usr/lib/systemd/system/shellcrash.service + rm -rf /www/clash + rm -rf /tmp/ShellCrash + rm -rf /usr/bin/crash + sed -i '/0:7890/d' /etc/passwd + userdel -r shellcrash 2>/dev/null + nvram set script_usbmount="" 2>/dev/null + nvram commit 2>/dev/null + uci delete firewall.ShellCrash 2>/dev/null + uci commit firewall 2>/dev/null + echo "-----------------------------------------------" + echo -e "\033[36m已卸载ShellCrash相关文件!有缘再会!\033[0m" + echo -e "\033[33m请手动关闭当前窗口以重置环境变量!\033[0m" + echo "-----------------------------------------------" + exit + else + echo -e "\033[31m操作已取消!\033[0m" + fi } tools() { - ssh_tools() { - stop_iptables() { - iptables -w -t nat -D PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 - ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 - } - [ -n "$(cat /etc/firewall.user 2>&1 | grep '启用外网访问SSH服务')" ] && ssh_ol=禁止 || ssh_ol=开启 - [ -z "$ssh_port" ] && ssh_port=10022 - echo ----------------------------------------------- - echo -e "\033[33m此功能仅针对使用Openwrt系统的设备生效,且不依赖服务\033[0m" - echo -e "\033[31m本功能不支持红米AX6S等镜像化系统设备,请勿尝试!\033[0m" - echo ----------------------------------------------- - echo -e " 1 \033[32m修改\033[0m外网访问端口:\033[36m$ssh_port\033[0m" - echo -e " 2 \033[32m修改\033[0mSSH访问密码(请连续输入2次后回车)" - echo -e " 3 \033[33m$ssh_ol\033[0m外网访问SSH" - echo ----------------------------------------------- - echo -e " 0 返回上级菜单 \033[0m" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= + ssh_tools() { + stop_iptables() { + iptables -w -t nat -D PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 + ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 >/dev/null 2>&1 + } + [ -n "$(cat /etc/firewall.user 2>&1 | grep '启用外网访问SSH服务')" ] && ssh_ol=禁止 || ssh_ol=开启 + [ -z "$ssh_port" ] && ssh_port=10022 + echo "-----------------------------------------------" + echo -e "\033[33m此功能仅针对使用Openwrt系统的设备生效,且不依赖服务\033[0m" + echo -e "\033[31m本功能不支持红米AX6S等镜像化系统设备,请勿尝试!\033[0m" + echo "-----------------------------------------------" + echo -e " 1 \033[32m修改\033[0m外网访问端口:\033[36m$ssh_port\033[0m" + echo -e " 2 \033[32m修改\033[0mSSH访问密码(请连续输入2次后回车)" + echo -e " 3 \033[33m$ssh_ol\033[0m外网访问SSH" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单 \033[0m" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + case "$num" in + 0) + i= + ;; + 1) + read -p "请输入端口号(1000-65535) > " num + if [ -z "$num" ]; then + errornum + elif [ $num -gt 65535 -o $num -le 999 ]; then + echo -e "\033[31m输入错误!请输入正确的数值(1000-65535)!\033[0m" + elif [ -n "$(netstat -ntul | grep :$num)" ]; then + echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" + else + ssh_port=$num + setconfig ssh_port $ssh_port + sed -i "/启用外网访问SSH服务/d" /etc/firewall.user + stop_iptables + echo -e "\033[32m设置成功,请重新开启外网访问SSH功能!!!\033[0m" + fi + sleep 1 + ssh_tools + ;; + 2) + passwd + sleep 1 + ssh_tools + ;; + 3) + if [ "$ssh_ol" = "开启" ]; then + iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 + [ -n "$(ckcmd ip6tables)" ] && ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 + echo "iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user + [ -n "$(ckcmd ip6tables)" ] && echo "ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user + echo "-----------------------------------------------" + echo -e "已开启外网访问SSH功能!" + else + sed -i "/启用外网访问SSH服务/d" /etc/firewall.user + stop_iptables + echo "-----------------------------------------------" + echo -e "已禁止外网访问SSH!" + fi + ;; + *) + errornum + ;; + esac + } + #获取设置默认显示 + grep -qE "^\s*[^#].*otapredownload" /etc/crontabs/root >/dev/null 2>&1 && mi_update=禁用 || mi_update=启用 + [ "$mi_autoSSH" = "已配置" ] && mi_autoSSH_type=32m已配置 || mi_autoSSH_type=31m未配置 + [ -f ${CRASHDIR}/tools/tun.ko ] && mi_tunfix=32m已启用 || mi_tunfix=31m未启用 + # + echo "-----------------------------------------------" + echo -e "\033[30;47m欢迎使用其他工具菜单:\033[0m" + echo -e "\033[33m本页工具可能无法兼容全部Linux设备,请酌情使用!\033[0m" + echo -e "磁盘占用/所在目录:" + du -sh ${CRASHDIR} + echo "-----------------------------------------------" + echo -e " 1 ShellCrash\033[33m测试菜单\033[0m" + echo -e " 2 ShellCrash\033[32m新手引导\033[0m" + echo -e " 3 \033[36m日志及推送工具\033[0m" + [ -f /etc/firewall.user ] && echo -e " 4 \033[32m配置\033[0m外网访问SSH" + [ -x /usr/sbin/otapredownload ] && echo -e " 5 \033[33m$mi_update\033[0m小米系统自动更新" + [ "$systype" = "mi_snapshot" ] && echo -e " 6 小米设备软固化SSH ———— \033[$mi_autoSSH_type \033[0m" + [ -f /etc/config/ddns ] && echo -e " 7 配置\033[32mDDNS服务\033[0m(需下载相关脚本)" + [ "$systype" = "mi_snapshot" ] && echo -e " 8 小米设备Tun模块修复 ———— \033[$mi_tunfix \033[0m" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + read -p "请输入对应数字 > " num + if [ -z "$num" ]; then + errornum + elif [ "$num" = 0 ]; then + i= - elif [ "$num" = 1 ]; then - read -p "请输入端口号(1000-65535) > " num - if [ -z "$num" ]; then - errornum - elif [ $num -gt 65535 -o $num -le 999 ]; then - echo -e "\033[31m输入错误!请输入正确的数值(1000-65535)!\033[0m" - elif [ -n "$(netstat -ntul | grep :$num)" ]; then - echo -e "\033[31m当前端口已被其他进程占用,请重新输入!\033[0m" - else - ssh_port=$num - setconfig ssh_port $ssh_port - sed -i "/启用外网访问SSH服务/d" /etc/firewall.user - stop_iptables - echo -e "\033[32m设置成功,请重新开启外网访问SSH功能!!!\033[0m" - fi - sleep 1 - ssh_tools + elif [ "$num" = 1 ]; then + . ${CRASHDIR}/webget.sh && testcommand - elif [ "$num" = 2 ]; then - passwd - sleep 1 - ssh_tools + elif [ "$num" = 2 ]; then + . ${CRASHDIR}/webget.sh && userguide - elif [ "$num" = 3 ]; then - if [ "$ssh_ol" = "开启" ]; then - iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 - [ -n "$(ckcmd ip6tables)" ] && ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 - echo "iptables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user - [ -n "$(ckcmd ip6tables)" ] && echo "ip6tables -w -t nat -A PREROUTING -p tcp -m multiport --dports $ssh_port -j REDIRECT --to-ports 22 #启用外网访问SSH服务" >>/etc/firewall.user - echo ----------------------------------------------- - echo -e "已开启外网访问SSH功能!" - else - sed -i "/启用外网访问SSH服务/d" /etc/firewall.user - stop_iptables - echo ----------------------------------------------- - echo -e "已禁止外网访问SSH!" - fi - else - errornum - fi - } - #获取设置默认显示 - grep -qE "^\s*[^#].*otapredownload" /etc/crontabs/root >/dev/null 2>&1 && mi_update=禁用 || mi_update=启用 - [ "$mi_autoSSH" = "已配置" ] && mi_autoSSH_type=32m已配置 || mi_autoSSH_type=31m未配置 - [ -f ${CRASHDIR}/tools/tun.ko ] && mi_tunfix=32m已启用 || mi_tunfix=31m未启用 - # - echo ----------------------------------------------- - echo -e "\033[30;47m欢迎使用其他工具菜单:\033[0m" - echo -e "\033[33m本页工具可能无法兼容全部Linux设备,请酌情使用!\033[0m" - echo -e "磁盘占用/所在目录:" - du -sh ${CRASHDIR} - echo ----------------------------------------------- - echo -e " 1 ShellCrash\033[33m测试菜单\033[0m" - echo -e " 2 ShellCrash\033[32m新手引导\033[0m" - echo -e " 3 \033[36m日志及推送工具\033[0m" - [ -f /etc/firewall.user ] && echo -e " 4 \033[32m配置\033[0m外网访问SSH" - [ -x /usr/sbin/otapredownload ] && echo -e " 5 \033[33m$mi_update\033[0m小米系统自动更新" - [ "$systype" = "mi_snapshot" ] && echo -e " 6 小米设备软固化SSH ———— \033[$mi_autoSSH_type \033[0m" - [ -f /etc/config/ddns ] && echo -e " 7 配置\033[32mDDNS服务\033[0m(需下载相关脚本)" - [ "$systype" = "mi_snapshot" ] && echo -e " 8 小米设备Tun模块修复 ———— \033[$mi_tunfix \033[0m" - echo ----------------------------------------------- - echo -e " 0 返回上级菜单" - echo ----------------------------------------------- - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then - i= + elif [ "$num" = 3 ]; then + log_pusher + tools - elif [ "$num" = 1 ]; then - . ${CRASHDIR}/webget.sh && testcommand + elif [ "$num" = 4 ]; then + ssh_tools + sleep 1 + tools - elif [ "$num" = 2 ]; then - . ${CRASHDIR}/webget.sh && userguide + elif [ "$num" = 7 ]; then + echo "-----------------------------------------------" + if [ ! -f ${CRASHDIR}/tools/ShellDDNS.sh ]; then + echo -e "正在获取在线脚本……" + ${CRASHDIR}/start.sh get_bin ${TMPDIR}/ShellDDNS.sh tools/ShellDDNS.sh + if [ "$?" = "0" ]; then + mv -f ${TMPDIR}/ShellDDNS.sh ${CRASHDIR}/tools/ShellDDNS.sh + . ${CRASHDIR}/tools/ShellDDNS.sh + else + echo -e "\033[31m文件下载失败!\033[0m" + fi + else + . ${CRASHDIR}/tools/ShellDDNS.sh + fi + sleep 1 + tools - elif [ "$num" = 3 ]; then - log_pusher - tools + elif [ -x /usr/sbin/otapredownload ] && [ "$num" = 5 ]; then + if [ "$mi_update" = "禁用" ]; then + grep -q "otapredownload" /etc/crontabs/root && + sed -i "/^[^\#]*otapredownload/ s/^/#/" /etc/crontabs/root || + echo "#15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root + else + grep -q "otapredownload" /etc/crontabs/root && + sed -i "/^\s*#.*otapredownload/ s/^\s*#//" /etc/crontabs/root || + echo "15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root + fi + echo "-----------------------------------------------" + echo -e "已\033[33m$mi_update\033[0m小米路由器的自动更新,如未生效,请在官方APP中同步设置!" + sleep 1 + tools - elif [ "$num" = 4 ]; then - ssh_tools - sleep 1 - tools - - elif [ "$num" = 7 ]; then - echo ----------------------------------------------- - if [ ! -f ${CRASHDIR}/tools/ShellDDNS.sh ]; then - echo -e "正在获取在线脚本……" - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/ShellDDNS.sh tools/ShellDDNS.sh - if [ "$?" = "0" ]; then - mv -f ${TMPDIR}/ShellDDNS.sh ${CRASHDIR}/tools/ShellDDNS.sh - . ${CRASHDIR}/tools/ShellDDNS.sh - else - echo -e "\033[31m文件下载失败!\033[0m" - fi - else - . ${CRASHDIR}/tools/ShellDDNS.sh - fi - sleep 1 - tools - - elif [ -x /usr/sbin/otapredownload ] && [ "$num" = 5 ]; then - if [ "$mi_update" = "禁用" ]; then - grep -q "otapredownload" /etc/crontabs/root && - sed -i "/^[^\#]*otapredownload/ s/^/#/" /etc/crontabs/root || - echo "#15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root - else - grep -q "otapredownload" /etc/crontabs/root && - sed -i "/^\s*#.*otapredownload/ s/^\s*#//" /etc/crontabs/root || - echo "15 3,4,5 * * * /usr/sbin/otapredownload >/dev/null 2>&1" >>/etc/crontabs/root - fi - echo ----------------------------------------------- - echo -e "已\033[33m$mi_update\033[0m小米路由器的自动更新,如未生效,请在官方APP中同步设置!" - sleep 1 - tools - - elif [ "$num" = 6 ]; then - if [ "$systype" = "mi_snapshot" ]; then - autoSSH - else - echo 不支持的设备! - fi - tools - elif [ "$num" = 8 ]; then - if [ -f ${CRASHDIR}/tools/tun.ko ]; then - read -p "是否禁用此功能并移除相关补丁?(1/0) > " res - [ "$res" = 1 ] && { - rm -rf ${CRASHDIR}/tools/tun.ko - echo -e "\033[33m补丁文件已移除,请立即重启设备以防止出错!\033[0m" - } - elif ckcmd modinfo && [ -z "$(modinfo tun)" ]; then - echo -e "\033[33m本功能需要修改系统文件,不保证没有任何风险!\033[0m" - echo -e "\033[33m本功能采集的Tun模块并不一定适用于你的设备!\033[0m" - sleep 1 - read -p "我已知晓,出现问题会自行承担!(1/0) > " res - if [ "$res" = 1 ]; then - echo ----------------------------------------------- - echo 正在连接服务器获取Tun模块补丁文件………… - ${CRASHDIR}/start.sh get_bin ${TMPDIR}/tun.ko bin/fix/tun.ko - if [ "$?" = "0" ]; then - mv -f ${TMPDIR}/tun.ko ${CRASHDIR}/tools/tun.ko && - ${CRASHDIR}/misnap_init.sh tunfix && - echo -e "\033[32m设置成功!请重启服务!\033[0m" - else - echo -e "\033[31m文件下载失败,请重试!\033[0m" - fi - fi - else - echo -e "\033[31m当前设备无需设置,请勿尝试!\033[0m" - sleep 1 - fi - tools - else - errornum - fi + elif [ "$num" = 6 ]; then + if [ "$systype" = "mi_snapshot" ]; then + autoSSH + else + echo "不支持的设备!" + fi + tools + elif [ "$num" = 8 ]; then + if [ -f ${CRASHDIR}/tools/tun.ko ]; then + read -p "是否禁用此功能并移除相关补丁?(1/0) > " res + [ "$res" = 1 ] && { + rm -rf ${CRASHDIR}/tools/tun.ko + echo -e "\033[33m补丁文件已移除,请立即重启设备以防止出错!\033[0m" + } + elif ckcmd modinfo && [ -z "$(modinfo tun)" ]; then + echo -e "\033[33m本功能需要修改系统文件,不保证没有任何风险!\033[0m" + echo -e "\033[33m本功能采集的Tun模块并不一定适用于你的设备!\033[0m" + sleep 1 + read -p "我已知晓,出现问题会自行承担!(1/0) > " res + if [ "$res" = 1 ]; then + echo "-----------------------------------------------" + echo "正在连接服务器获取Tun模块补丁文件…………" + ${CRASHDIR}/start.sh get_bin ${TMPDIR}/tun.ko bin/fix/tun.ko + if [ "$?" = "0" ]; then + mv -f ${TMPDIR}/tun.ko ${CRASHDIR}/tools/tun.ko && + ${CRASHDIR}/misnap_init.sh tunfix && + echo -e "\033[32m设置成功!请重启服务!\033[0m" + else + echo -e "\033[31m文件下载失败,请重试!\033[0m" + fi + fi + else + echo -e "\033[31m当前设备无需设置,请勿尝试!\033[0m" + sleep 1 + fi + tools + else + errornum + fi } #主菜单 main_menu() { - ############################# - ckstatus - ############################# - echo -e " 1 \033[32m启动/重启\033[0m服务" - echo -e " 2 内核\033[33m功能设置\033[0m" - echo -e " 3 \033[31m停止\033[0m内核服务" - echo -e " 4 内核\033[36m启动设置\033[0m" - echo -e " 5 配置\033[33m自动任务\033[0m" - echo -e " 6 导入\033[32m配置文件\033[0m" - echo -e " 7 内核\033[31m进阶设置\033[0m" - echo -e " 8 \033[35m其他工具\033[0m" - echo -e " 9 \033[36m更新/卸载\033[0m" - echo ----------------------------------------------- - echo -e " 0 \033[0m退出脚本\033[0m" - read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - exit + ############################# + ckstatus + ############################# + echo -e " 1 \033[32m启动/重启\033[0m服务" + echo -e " 2 内核\033[33m功能设置\033[0m" + echo -e " 3 \033[31m停止\033[0m内核服务" + echo -e " 4 内核\033[36m启动设置\033[0m" + echo -e " 5 配置\033[33m自动任务\033[0m" + echo -e " 6 导入\033[32m配置文件\033[0m" + echo -e " 7 内核\033[31m进阶设置\033[0m" + echo -e " 8 \033[35m其他工具\033[0m" + echo -e " 9 \033[36m更新/卸载\033[0m" + echo "-----------------------------------------------" + echo -e " 0 \033[0m退出脚本\033[0m" + read -p "请输入对应数字 > " num - elif [ "$num" = 0 ]; then - exit - - elif [ "$num" = 1 ]; then - start_service - exit - - elif [ "$num" = 2 ]; then - checkcfg=$(cat $CFG_PATH) - normal_set - if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - - elif [ "$num" = 3 ]; then - ${CRASHDIR}/start.sh stop - sleep 1 - echo ----------------------------------------------- - echo -e "\033[31m$corename服务已停止!\033[0m" - main_menu - - elif [ "$num" = 4 ]; then - setboot - main_menu - - elif [ "$num" = 5 ]; then - . ${CRASHDIR}/task/task.sh && task_menu - main_menu - - elif [ "$num" = 6 ]; then - . ${CRASHDIR}/webget.sh && set_core_config - main_menu - - elif [ "$num" = 7 ]; then - checkcfg=$(cat $CFG_PATH) - advanced_set - if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - - elif [ "$num" = 8 ]; then - tools - main_menu - - elif [ "$num" = 9 ]; then - checkcfg=$(cat $CFG_PATH) - . ${CRASHDIR}/webget.sh && update - if [ -n "$PID" ]; then - checkcfg_new=$(cat $CFG_PATH) - [ "$checkcfg" != "$checkcfg_new" ] && checkrestart - fi - main_menu - - else - errornum - exit - fi + case "$num" in + 0) + exit + ;; + 1) + start_service + exit + ;; + 2) + checkcfg=$(cat $CFG_PATH) + normal_set + if [ -n "$PID" ]; then + checkcfg_new=$(cat $CFG_PATH) + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + main_menu + ;; + 3) + ${CRASHDIR}/start.sh stop + sleep 1 + echo "-----------------------------------------------" + echo -e "\033[31m$corename服务已停止!\033[0m" + main_menu + ;; + 4) + setboot + main_menu + ;; + 5) + . ${CRASHDIR}/task/task.sh && task_menu + main_menu + ;; + 6) + . ${CRASHDIR}/webget.sh && set_core_config + main_menu + ;; + 7) + checkcfg=$(cat $CFG_PATH) + advanced_set + if [ -n "$PID" ]; then + checkcfg_new=$(cat $CFG_PATH) + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + main_menu + ;; + 8) + tools + main_menu + ;; + 9) + checkcfg=$(cat $CFG_PATH) + . ${CRASHDIR}/webget.sh && update + if [ -n "$PID" ]; then + checkcfg_new=$(cat $CFG_PATH) + [ "$checkcfg" != "$checkcfg_new" ] && checkrestart + fi + main_menu + ;; + *) + errornum + exit + ;; + esac } [ -z "$CRASHDIR" ] && { - echo 环境变量配置有误!正在初始化~~~ - CRASHDIR=$( - cd $(dirname $0) - pwd - ) - . ${CRASHDIR}/init.sh - sleep 1 - echo 请重启SSH窗口以完成初始化! - exit + echo "环境变量配置有误!正在初始化~~~" + CRASHDIR=$( + cd $(dirname $0) + pwd + ) + . ${CRASHDIR}/init.sh + sleep 1 + echo "请重启SSH窗口以完成初始化!" + exit } [ -z "$1" ] && main_menu case "$1" in -h) - echo ----------------------------------------- - echo "欢迎使用ShellCrash" - echo ----------------------------------------- - echo " -t 测试模式" - echo " -h 帮助列表" - echo " -u 卸载脚本" - echo " -i 初始化脚本" - echo " -d 测试运行" - echo ----------------------------------------- - echo " crash -s start 启动服务" - echo " crash -s stop 停止服务" - echo " 安装目录/start.sh init 开机初始化" - echo ----------------------------------------- - echo "在线求助:t.me/ShellClash" - echo "官方博客:juewuy.github.io" - echo "发布页面:github.com/juewuy/ShellCrash" - echo ----------------------------------------- - ;; + echo ----------------------------------------- + echo "欢迎使用ShellCrash" + echo ----------------------------------------- + echo " -t 测试模式" + echo " -h 帮助列表" + echo " -u 卸载脚本" + echo " -i 初始化脚本" + echo " -d 测试运行" + echo ----------------------------------------- + echo " crash -s start 启动服务" + echo " crash -s stop 停止服务" + echo " 安装目录/start.sh init 开机初始化" + echo ----------------------------------------- + echo "在线求助:t.me/ShellClash" + echo "官方博客:juewuy.github.io" + echo "发布页面:github.com/juewuy/ShellCrash" + echo ----------------------------------------- + ;; -t) - shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash - $shtype -x ${CRASHDIR}/menu.sh - ;; + shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash + $shtype -x ${CRASHDIR}/menu.sh + ;; -s) - ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 - ;; + ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 + ;; -i) - . ${CRASHDIR}/init.sh - ;; + . ${CRASHDIR}/init.sh + ;; -st) - shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash - $shtype -x ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 - ;; + shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash + $shtype -x ${CRASHDIR}/start.sh $2 $3 $4 $5 $6 + ;; -d) - shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash - echo -e "正在测试运行!如发现错误请截图后前往\033[32;4mt.me/ShellClash\033[0m咨询" - $shtype ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh_bug.log - $shtype -x ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh.log - echo ----------------------------------------- - cat ${TMPDIR}/debug_sh_bug.log | grep 'start\.sh' >${TMPDIR}/sh_bug - if [ -s ${TMPDIR}/sh_bug ]; then - while read line; do - echo -e "发现错误:\033[33;4m$line\033[0m" - grep -A 1 -B 3 "$line" ${TMPDIR}/debug_sh.log - echo ----------------------------------------- - done <${TMPDIR}/sh_bug - rm -rf ${TMPDIR}/sh_bug - echo -e "\033[32m测试完成!\033[0m完整执行记录请查看:\033[36m${TMPDIR}/debug_sh.log\033[0m" - else - echo -e "\033[32m测试完成!没有发现问题,请重新启动服务~\033[0m" - rm -rf ${TMPDIR}/debug_sh.log - fi - ${CRASHDIR}/start.sh stop - ;; + shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash + echo -e "正在测试运行!如发现错误请截图后前往\033[32;4mt.me/ShellClash\033[0m咨询" + $shtype ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh_bug.log + $shtype -x ${CRASHDIR}/start.sh debug >/dev/null 2>${TMPDIR}/debug_sh.log + echo ----------------------------------------- + cat ${TMPDIR}/debug_sh_bug.log | grep 'start\.sh' >${TMPDIR}/sh_bug + if [ -s ${TMPDIR}/sh_bug ]; then + while read line; do + echo -e "发现错误:\033[33;4m$line\033[0m" + grep -A 1 -B 3 "$line" ${TMPDIR}/debug_sh.log + echo ----------------------------------------- + done <${TMPDIR}/sh_bug + rm -rf ${TMPDIR}/sh_bug + echo -e "\033[32m测试完成!\033[0m完整执行记录请查看:\033[36m${TMPDIR}/debug_sh.log\033[0m" + else + echo -e "\033[32m测试完成!没有发现问题,请重新启动服务~\033[0m" + rm -rf ${TMPDIR}/debug_sh.log + fi + ${CRASHDIR}/start.sh stop + ;; -u) - uninstall - ;; + uninstall + ;; *) - $0 -h - ;; + $0 -h + ;; esac diff --git a/scripts/start.sh b/scripts/start.sh index 6b7d96c2..5ce326e7 100644 --- a/scripts/start.sh +++ b/scripts/start.sh @@ -3,8 +3,8 @@ #初始化目录 CRASHDIR=$( - cd $(dirname $0) - pwd + cd $(dirname $0) + pwd ) #加载执行目录,失败则初始化 . "$CRASHDIR"/configs/command.env >/dev/null 2>&1 @@ -13,411 +13,411 @@ CRASHDIR=$( #脚本内部工具 getconfig() { #读取配置及全局变量 - #加载配置文件 - . "$CRASHDIR"/configs/ShellCrash.cfg >/dev/null - #缺省值 - [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod=Redir模式 - [ -z "$redir_mod" ] && redir_mod=纯净模式 - [ -z "$skip_cert" ] && skip_cert=已开启 - [ -z "$dns_mod" ] && dns_mod=fake-ip - [ -z "$ipv6_redir" ] && ipv6_redir=未开启 - [ -z "$ipv6_dns" ] && ipv6_dns=已开启 - [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 - [ -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='180.184.1.1, 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"/configs/ShellCrash.cfg >/dev/null + #缺省值 + [ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod=Redir模式 + [ -z "$redir_mod" ] && redir_mod=纯净模式 + [ -z "$skip_cert" ] && skip_cert=已开启 + [ -z "$dns_mod" ] && dns_mod=fake-ip + [ -z "$ipv6_redir" ] && ipv6_redir=未开启 + [ -z "$ipv6_dns" ] && ipv6_dns=已开启 + [ -z "$cn_ipv6_route" ] && cn_ipv6_route=未开启 + [ -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='180.184.1.1, 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 } 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 + #参数1代表变量名,参数2代表变量值,参数3即文件路径 + [ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}" + if grep -q "^${1}=" "$configpath"; then + sed -i "s#${1}=.*#${1}=${2}#g" "$configpath" + else + printf '%s=%s\n' "$1" "$2" >>"$configpath" + fi } ckcmd() { #检查命令是否存在 - command -v sh >/dev/null 2>&1 && command -v "$1" >/dev/null 2>&1 || type "$1" >/dev/null 2>&1 + command -v sh >/dev/null 2>&1 && command -v "$1" >/dev/null 2>&1 || type "$1" >/dev/null 2>&1 } ckgeo() { #查找及下载Geo数据文件 - [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset - find --help 2>&1 | grep -q size && find_para=' -size +20' #find命令兼容 - [ -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 - } + [ ! -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 + } } compare() { #对比文件 - if [ ! -f "$1" ] || [ ! -f "$2" ]; then - return 1 - elif ckcmd cmp; then - cmp -s "$1" "$2" - else - [ "$(cat "$1")" = "$(cat "$2")" ] && return 0 || return 1 - fi + if [ ! -f "$1" ] || [ ! -f "$2" ]; then + return 1 + elif ckcmd cmp; then + cmp -s "$1" "$2" + else + [ "$(cat "$1")" = "$(cat "$2")" ] && return 0 || return 1 + fi } logger() { #日志工具 - #$1日志内容$2显示颜色$3是否推送 - [ -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 - [ "$(wc -l "$TMPDIR"/ShellCrash.log | awk '{print $1}')" -gt 99 ] && sed -i '1,50d' "$TMPDIR"/ShellCrash.log - #推送工具 - webpush() { - [ -n "$(pidof CrashCore)" ] && { - [ -n "$authentication" ] && auth="$authentication@" - export https_proxy="http://${auth}127.0.0.1:$mix_port" - } - if curl --version >/dev/null 2>&1; then - curl -kfsSl -X POST --connect-timeout 3 -H "Content-Type: application/json; charset=utf-8" "$1" -d "$2" >/dev/null 2>&1 - elif wget --version >/dev/null 2>&1; then - wget -Y on -q --timeout=3 -O - --method=POST --header="Content-Type: application/json; charset=utf-8" --body-data="$2" "$1" >/dev/null 2>&1 - else - echo "找不到有效的curl或wget应用,请先安装!" - fi - } - [ -z "$3" ] && { - [ -n "$device_name" ] && log_text="$log_text($device_name)" - [ -n "$push_TG" ] && { - url="https://api.telegram.org/bot${push_TG}/sendMessage" - [ "$push_TG" = 'publictoken' ] && url='https://tgbot.jwsc.eu.org/publictoken/sendMessage' - content="{\"chat_id\":\"${chat_ID}\",\"text\":\"$log_text\"}" - webpush "$url" "$content" & - } - [ -n "$push_bark" ] && { - url="${push_bark}" - content="{\"body\":\"${log_text}\",\"title\":\"ShellCrash日志推送\",\"level\":\"passive\",\"badge\":\"1\"}" - webpush "$url" "$content" & - } - [ -n "$push_Deer" ] && { - url="https://api2.pushdeer.com/message/push" - content="{\"pushkey\":\"${push_Deer}\",\"text\":\"$log_text\"}" - webpush "$url" "$content" & - } - [ -n "$push_Po" ] && { - url="https://api.pushover.net/1/messages.json" - content="{\"token\":\"${push_Po}\",\"user\":\"${push_Po_key}\",\"title\":\"ShellCrash日志推送\",\"message\":\"$log_text\"}" - webpush "$url" "$content" & - } - [ -n "$push_PP" ] && { - url="http://www.pushplus.plus/send" - content="{\"token\":\"${push_PP}\",\"title\":\"ShellCrash日志推送\",\"content\":\"$log_text\"}" - webpush "$url" "$content" & - } - # 新增Gotify推送 - [ -n "$push_Gotify" ] && { - url="${push_Gotify}" - content="{\"title\":\"ShellCrash日志推送\",\"message\":\"$log_text\",\"priority\":5}" - webpush "$url" "$content" & - } - [ -n "$push_SynoChat" ] && { - url="${push_ChatURL}/webapi/entry.cgi?api=SYNO.Chat.External&method=chatbot&version=2&token=${push_ChatTOKEN}" - content="payload={\"text\":\"${log_text}\", \"user_ids\":[${push_ChatUSERID}]}" - webpush "$url" "$content" & - #curl -X POST "${push_ChatURL}/webapi/entry.cgi?api=SYNO.Chat.External&method=chatbot&version=2&token=${push_ChatTOKEN}" -H 'content-Type: application/json' -d "payload={\"text\":\"${log_text}\", \"user_ids\":[${push_ChatUSERID}]}" >/dev/null 2>&1 - } - } & + #$1日志内容$2显示颜色$3是否推送 + [ -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 + [ "$(wc -l "$TMPDIR"/ShellCrash.log | awk '{print $1}')" -gt 99 ] && sed -i '1,50d' "$TMPDIR"/ShellCrash.log + #推送工具 + webpush() { + [ -n "$(pidof CrashCore)" ] && { + [ -n "$authentication" ] && auth="$authentication@" + export https_proxy="http://${auth}127.0.0.1:$mix_port" + } + if curl --version >/dev/null 2>&1; then + curl -kfsSl -X POST --connect-timeout 3 -H "Content-Type: application/json; charset=utf-8" "$1" -d "$2" >/dev/null 2>&1 + elif wget --version >/dev/null 2>&1; then + wget -Y on -q --timeout=3 -O - --method=POST --header="Content-Type: application/json; charset=utf-8" --body-data="$2" "$1" >/dev/null 2>&1 + else + echo "找不到有效的curl或wget应用,请先安装!" + fi + } + [ -z "$3" ] && { + [ -n "$device_name" ] && log_text="$log_text($device_name)" + [ -n "$push_TG" ] && { + url="https://api.telegram.org/bot${push_TG}/sendMessage" + [ "$push_TG" = 'publictoken' ] && url='https://tgbot.jwsc.eu.org/publictoken/sendMessage' + content="{\"chat_id\":\"${chat_ID}\",\"text\":\"$log_text\"}" + webpush "$url" "$content" & + } + [ -n "$push_bark" ] && { + url="${push_bark}" + content="{\"body\":\"${log_text}\",\"title\":\"ShellCrash日志推送\",\"level\":\"passive\",\"badge\":\"1\"}" + webpush "$url" "$content" & + } + [ -n "$push_Deer" ] && { + url="https://api2.pushdeer.com/message/push" + content="{\"pushkey\":\"${push_Deer}\",\"text\":\"$log_text\"}" + webpush "$url" "$content" & + } + [ -n "$push_Po" ] && { + url="https://api.pushover.net/1/messages.json" + content="{\"token\":\"${push_Po}\",\"user\":\"${push_Po_key}\",\"title\":\"ShellCrash日志推送\",\"message\":\"$log_text\"}" + webpush "$url" "$content" & + } + [ -n "$push_PP" ] && { + url="http://www.pushplus.plus/send" + content="{\"token\":\"${push_PP}\",\"title\":\"ShellCrash日志推送\",\"content\":\"$log_text\"}" + webpush "$url" "$content" & + } + # 新增Gotify推送 + [ -n "$push_Gotify" ] && { + url="${push_Gotify}" + content="{\"title\":\"ShellCrash日志推送\",\"message\":\"$log_text\",\"priority\":5}" + webpush "$url" "$content" & + } + [ -n "$push_SynoChat" ] && { + url="${push_ChatURL}/webapi/entry.cgi?api=SYNO.Chat.External&method=chatbot&version=2&token=${push_ChatTOKEN}" + content="payload={\"text\":\"${log_text}\", \"user_ids\":[${push_ChatUSERID}]}" + webpush "$url" "$content" & + #curl -X POST "${push_ChatURL}/webapi/entry.cgi?api=SYNO.Chat.External&method=chatbot&version=2&token=${push_ChatTOKEN}" -H 'content-Type: application/json' -d "payload={\"text\":\"${log_text}\", \"user_ids\":[${push_ChatUSERID}]}" >/dev/null 2>&1 + } + } & } 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 + 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" - rm -f "$tmpcron" + # 参数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" + 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 + 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 + [ -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" + [ -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 + 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" + 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" } #配置文件相关 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 - } + #检测节点或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" + #检测节点或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 +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转码处理保留字符 - Url=$(echo $Url | sed 's/;/\%3B/g; s|/|\%2F|g; s/?/\%3F/g; s/:/\%3A/g; s/@/\%40/g; s/=/\%3D/g; s/&/\%26/g') - Https="${Server}/sub?target=${target}&${Server_ua}=${user_agent}&insert=true&new_name=true&scv=true&udp=true&exclude=${exclude}&include=${include}&url=${Url}&config=${Config}" - 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 [ "$?" = "1" ]; then - if [ -z "$url_type" ]; then - echo ----------------------------------------------- - logger "配置文件获取失败!" 31 - echo -e "\033[31m请尝试使用【在线生成配置文件】功能!\033[0m" - echo ----------------------------------------------- - exit 1 - else - if [ "$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 + [ -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转码处理保留字符 + Url=$(echo $Url | sed 's/;/\%3B/g; s|/|\%2F|g; s/?/\%3F/g; s/:/\%3A/g; s/@/\%40/g; s/=/\%3D/g; s/&/\%26/g') + Https="${Server}/sub?target=${target}&${Server_ua}=${user_agent}&insert=true&new_name=true&scv=true&udp=true&exclude=${exclude}&include=${include}&url=${Url}&config=${Config}" + 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 [ "$?" = "1" ]; then + if [ -z "$url_type" ]; then + echo "-----------------------------------------------" + logger "配置文件获取失败!" 31 + echo -e "\033[31m请尝试使用【在线生成配置文件】功能!\033[0m" + echo "-----------------------------------------------" + exit 1 + else + if [ "$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 '^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 </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"/dns.yaml <"$TMPDIR"/set.yaml <"$TMPDIR"/set.yaml </dev/null)" ]; then - #NTP劫持 - cat >"$TMPDIR"/hosts.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' - 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=$(grep -A 1 'proxies:$' "$TMPDIR"/proxy-groups.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') - #合并自定义策略组到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" >"$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 - } - #节点绕过功能支持 - 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模式生成rule-providers - [ "$dns_mod" = "mix" ] && ! 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 + if [ "$crashcore" = "meta" ]; then + echo " 'services.googleapis.cn': services.googleapis.com" >>"$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' + 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=$(grep -A 1 'proxies:$' "$TMPDIR"/proxy-groups.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') + #合并自定义策略组到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" >"$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 + } + #节点绕过功能支持 + 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模式生成rule-providers + [ "$dns_mod" = "mix" ] && ! 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 - #生成log.json - cat >"$TMPDIR"/jsons/log.json <"$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 + #生成log.json + cat >"$TMPDIR"/jsons/log.json <"$TMPDIR"/jsons/add_hosts.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 </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/dns.json <"$TMPDIR"/jsons/add_route.json <"$TMPDIR"/jsons/add_route.json <"$TMPDIR"/jsons/certificate.json <"$TMPDIR"/jsons/certificate.json <"$TMPDIR"/jsons/inbounds.json <"$TMPDIR"/jsons/inbounds.json <>"$TMPDIR"/jsons/tun.json <>"$TMPDIR"/jsons/tun.json <"$TMPDIR"/jsons/add_outbounds.json <"$TMPDIR"/jsons/add_outbounds.json <"$TMPDIR"/jsons/experimental.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 + #生成自定义规则文件 + [ -n "$(grep -Ev ^# "$CRASHDIR"/yamls/rules.yaml 2>/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 - } + 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 - } + 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 + } } start_ipt_route() { #iptables-route通用工具 - #$1:iptables/ip6tables $2:所在的表(nat/mangle) $3:所在的链(OUTPUT/PREROUTING) $4:新创建的shellcrash链表 $5:tcp/udp/all - #区分ipv4/ipv6 - [ "$1" = 'iptables' ] && { - RESERVED_IP=$reserve_ipv4 - HOST_IP=$host_ipv4 - [ "$3" = 'OUTPUT' ] && HOST_IP="127.0.0.0/8 $local_ipv4" - [ "$4" = 'shellcrash_vm' ] && HOST_IP="$vm_ipv4" - iptables -h | grep -q '\-w' && w='-w' || w='' - } - [ "$1" = 'ip6tables' ] && { - RESERVED_IP=$reserve_ipv6 - HOST_IP=$host_ipv6 - [ "$3" = 'OUTPUT' ] && HOST_IP="::1 $host_ipv6" - ip6tables -h | grep -q '\-w' && w='-w' || w='' - } - #创建新的shellcrash链表 - $1 $w -t $2 -N $4 - #过滤dns - $1 $w -t $2 -A $4 -p tcp --dport 53 -j RETURN - $1 $w -t $2 -A $4 -p udp --dport 53 -j RETURN - #防回环 - $1 $w -t $2 -A $4 -m mark --mark $routing_mark -j RETURN - [ "$3" = 'OUTPUT' ] && for gid in 453 7890; do - $1 $w -t $2 -A $4 -m owner --gid-owner $gid -j RETURN - done - [ "$firewall_area" = 5 ] && $1 $w -t $2 -A $4 -s $bypass_host -j RETURN - [ -z "$ports" ] && $1 $w -t $2 -A $4 -p tcp -m multiport --dports "$mix_port,$redir_port,$tproxy_port" -j RETURN - #跳过目标保留地址及目标本机网段 - for ip in $HOST_IP $RESERVED_IP; do - $1 $w -t $2 -A $4 -d $ip -j RETURN - done - #绕过CN_IP - [ "$1" = iptables ] && [ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" = "已开启" ] && [ -f "$BINDIR"/cn_ip.txt ] && $1 $w -t $2 -A $4 -m set --match-set cn_ip dst -j RETURN 2>/dev/null - [ "$1" = ip6tables ] && [ "$dns_mod" != "fake-ip" ] && [ "$cn_ipv6_route" = "已开启" ] && [ -f "$BINDIR"/cn_ipv6.txt ] && $1 $w -t $2 -A $4 -m set --match-set cn_ip6 dst -j RETURN 2>/dev/null - #局域网mac地址黑名单过滤 - [ "$3" = 'PREROUTING' ] && [ "$macfilter_type" != "白名单" ] && { - [ -s "$CRASHDIR"/configs/mac ] && - for mac in $(cat "$CRASHDIR"/configs/mac); do - $1 $w -t $2 -A $4 -m mac --mac-source $mac -j RETURN - done - [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && - for ip in $(cat "$CRASHDIR"/configs/ip_filter); do - $1 $w -t $2 -A $4 -s $ip -j RETURN - done - } - #tcp&udp分别进代理链 - proxy_set() { - if [ "$3" = 'PREROUTING' ] && [ "$4" != 'shellcrash_vm' ] && [ "$macfilter_type" = "白名单" ] && [ -n "$(cat $CRASHDIR/configs/mac $CRASHDIR/configs/ip_filter 2>/dev/null)" ]; then - [ -s "$CRASHDIR"/configs/mac ] && - for mac in $(cat "$CRASHDIR"/configs/mac); do - $1 $w -t $2 -A $4 -p $5 -m mac --mac-source $mac -j $JUMP - done - [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && - for ip in $(cat "$CRASHDIR"/configs/ip_filter); do - $1 $w -t $2 -A $4 -p $5 -s $ip -j $JUMP - done - else - for ip in $HOST_IP; do #仅限指定网段流量 - $1 $w -t $2 -A $4 -p $5 -s $ip -j $JUMP - done - fi - #将所在链指定流量指向shellcrash表 - $1 $w -t $2 -I $3 -p $5 $ports -j $4 - [ "$dns_mod" = "mix" -o "$dns_mod" = "fake-ip" ] && [ "$common_ports" = "已开启" ] && [ "$1" = iptables ] && $1 $w -t $2 -I $3 -p $5 -d 28.0.0.1/8 -j $4 - [ "$dns_mod" = "mix" -o "$dns_mod" = "fake-ip" ] && [ "$common_ports" = "已开启" ] && [ "$1" = ip6tables ] && $1 $w -t $2 -I $3 -p $5 -d fc00::/16 -j $4 - } - [ "$5" = "tcp" -o "$5" = "all" ] && proxy_set $1 $2 $3 $4 tcp - [ "$5" = "udp" -o "$5" = "all" ] && proxy_set $1 $2 $3 $4 udp + #$1:iptables/ip6tables $2:所在的表(nat/mangle) $3:所在的链(OUTPUT/PREROUTING) $4:新创建的shellcrash链表 $5:tcp/udp/all + #区分ipv4/ipv6 + [ "$1" = 'iptables' ] && { + RESERVED_IP=$reserve_ipv4 + HOST_IP=$host_ipv4 + [ "$3" = 'OUTPUT' ] && HOST_IP="127.0.0.0/8 $local_ipv4" + [ "$4" = 'shellcrash_vm' ] && HOST_IP="$vm_ipv4" + iptables -h | grep -q '\-w' && w='-w' || w='' + } + [ "$1" = 'ip6tables' ] && { + RESERVED_IP=$reserve_ipv6 + HOST_IP=$host_ipv6 + [ "$3" = 'OUTPUT' ] && HOST_IP="::1 $host_ipv6" + ip6tables -h | grep -q '\-w' && w='-w' || w='' + } + #创建新的shellcrash链表 + $1 $w -t $2 -N $4 + #过滤dns + $1 $w -t $2 -A $4 -p tcp --dport 53 -j RETURN + $1 $w -t $2 -A $4 -p udp --dport 53 -j RETURN + #防回环 + $1 $w -t $2 -A $4 -m mark --mark $routing_mark -j RETURN + [ "$3" = 'OUTPUT' ] && for gid in 453 7890; do + $1 $w -t $2 -A $4 -m owner --gid-owner $gid -j RETURN + done + [ "$firewall_area" = 5 ] && $1 $w -t $2 -A $4 -s $bypass_host -j RETURN + [ -z "$ports" ] && $1 $w -t $2 -A $4 -p tcp -m multiport --dports "$mix_port,$redir_port,$tproxy_port" -j RETURN + #跳过目标保留地址及目标本机网段 + for ip in $HOST_IP $RESERVED_IP; do + $1 $w -t $2 -A $4 -d $ip -j RETURN + done + #绕过CN_IP + [ "$1" = iptables ] && [ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" = "已开启" ] && [ -f "$BINDIR"/cn_ip.txt ] && $1 $w -t $2 -A $4 -m set --match-set cn_ip dst -j RETURN 2>/dev/null + [ "$1" = ip6tables ] && [ "$dns_mod" != "fake-ip" ] && [ "$cn_ipv6_route" = "已开启" ] && [ -f "$BINDIR"/cn_ipv6.txt ] && $1 $w -t $2 -A $4 -m set --match-set cn_ip6 dst -j RETURN 2>/dev/null + #局域网mac地址黑名单过滤 + [ "$3" = 'PREROUTING' ] && [ "$macfilter_type" != "白名单" ] && { + [ -s "$CRASHDIR"/configs/mac ] && + for mac in $(cat "$CRASHDIR"/configs/mac); do + $1 $w -t $2 -A $4 -m mac --mac-source $mac -j RETURN + done + [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && + for ip in $(cat "$CRASHDIR"/configs/ip_filter); do + $1 $w -t $2 -A $4 -s $ip -j RETURN + done + } + #tcp&udp分别进代理链 + proxy_set() { + if [ "$3" = 'PREROUTING' ] && [ "$4" != 'shellcrash_vm' ] && [ "$macfilter_type" = "白名单" ] && [ -n "$(cat $CRASHDIR/configs/mac $CRASHDIR/configs/ip_filter 2>/dev/null)" ]; then + [ -s "$CRASHDIR"/configs/mac ] && + for mac in $(cat "$CRASHDIR"/configs/mac); do + $1 $w -t $2 -A $4 -p $5 -m mac --mac-source $mac -j $JUMP + done + [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && + for ip in $(cat "$CRASHDIR"/configs/ip_filter); do + $1 $w -t $2 -A $4 -p $5 -s $ip -j $JUMP + done + else + for ip in $HOST_IP; do #仅限指定网段流量 + $1 $w -t $2 -A $4 -p $5 -s $ip -j $JUMP + done + fi + #将所在链指定流量指向shellcrash表 + $1 $w -t $2 -I $3 -p $5 $ports -j $4 + [ "$dns_mod" = "mix" -o "$dns_mod" = "fake-ip" ] && [ "$common_ports" = "已开启" ] && [ "$1" = iptables ] && $1 $w -t $2 -I $3 -p $5 -d 28.0.0.1/8 -j $4 + [ "$dns_mod" = "mix" -o "$dns_mod" = "fake-ip" ] && [ "$common_ports" = "已开启" ] && [ "$1" = ip6tables ] && $1 $w -t $2 -I $3 -p $5 -d fc00::/16 -j $4 + } + [ "$5" = "tcp" -o "$5" = "all" ] && proxy_set $1 $2 $3 $4 tcp + [ "$5" = "udp" -o "$5" = "all" ] && proxy_set $1 $2 $3 $4 udp } start_ipt_dns() { #iptables-dns通用工具 - #$1:iptables/ip6tables $2:所在的表(OUTPUT/PREROUTING) $3:新创建的shellcrash表 - #区分ipv4/ipv6 - [ "$1" = 'iptables' ] && { - HOST_IP="$host_ipv4" - [ "$2" = 'OUTPUT' ] && HOST_IP="127.0.0.0/8 $local_ipv4" - [ "$3" = 'shellcrash_vm_dns' ] && HOST_IP="$vm_ipv4" - iptables -h | grep -q '\-w' && w='-w' || w='' - } - [ "$1" = 'ip6tables' ] && { - HOST_IP=$host_ipv6 - ip6tables -h | grep -q '\-w' && w='-w' || w='' - } - $1 $w -t nat -N $3 - #防回环 - $1 $w -t nat -A $3 -m mark --mark $routing_mark -j RETURN - [ "$2" = 'OUTPUT' ] && for gid in 453 7890; do - $1 $w -t nat -A $3 -m owner --gid-owner $gid -j RETURN - done - [ "$firewall_area" = 5 ] && { - $1 $w -t nat -A $3 -p tcp -s $bypass_host -j RETURN - $1 $w -t nat -A $3 -p udp -s $bypass_host -j RETURN - } - #局域网mac地址黑名单过滤 - [ "$2" = 'PREROUTING' ] && [ "$macfilter_type" != "白名单" ] && { - [ -s "$CRASHDIR"/configs/mac ] && - for mac in $(cat "$CRASHDIR"/configs/mac); do - $1 $w -t nat -A $3 -m mac --mac-source $mac -j RETURN - done - [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && - for ip in $(cat "$CRASHDIR"/configs/ip_filter); do - $1 $w -t nat -A $3 -s $ip -j RETURN - done - } - if [ "$2" = 'PREROUTING' ] && [ "$3" != 'shellcrash_vm_dns' ] && [ "$macfilter_type" = "白名单" ] && [ -n "$(cat $CRASHDIR/configs/mac $CRASHDIR/configs/ip_filter 2>/dev/null)" ]; then - [ -s "$CRASHDIR"/configs/mac ] && - for mac in $(cat "$CRASHDIR"/configs/mac); do - $1 $w -t nat -A $3 -p tcp -m mac --mac-source $mac -j REDIRECT --to-ports $dns_port - $1 $w -t nat -A $3 -p udp -m mac --mac-source $mac -j REDIRECT --to-ports $dns_port - done - [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && - for ip in $(cat "$CRASHDIR"/configs/ip_filter); do - $1 $w -t nat -A $3 -p tcp -s $ip -j REDIRECT --to-ports $dns_port - $1 $w -t nat -A $3 -p udp -s $ip -j REDIRECT --to-ports $dns_port - done - else - for ip in $HOST_IP; do #仅限指定网段流量 - $1 $w -t nat -A $3 -p tcp -s $ip -j REDIRECT --to-ports $dns_port - $1 $w -t nat -A $3 -p udp -s $ip -j REDIRECT --to-ports $dns_port - done - fi - [ "$1" = 'ip6tables' ] && { #屏蔽外部请求 - $1 $w -t nat -A $3 -p tcp -j RETURN - $1 $w -t nat -A $3 -p udp -j RETURN - } - $1 $w -t nat -I $2 -p tcp --dport 53 -j $3 - $1 $w -t nat -I $2 -p udp --dport 53 -j $3 + #$1:iptables/ip6tables $2:所在的表(OUTPUT/PREROUTING) $3:新创建的shellcrash表 + #区分ipv4/ipv6 + [ "$1" = 'iptables' ] && { + HOST_IP="$host_ipv4" + [ "$2" = 'OUTPUT' ] && HOST_IP="127.0.0.0/8 $local_ipv4" + [ "$3" = 'shellcrash_vm_dns' ] && HOST_IP="$vm_ipv4" + iptables -h | grep -q '\-w' && w='-w' || w='' + } + [ "$1" = 'ip6tables' ] && { + HOST_IP=$host_ipv6 + ip6tables -h | grep -q '\-w' && w='-w' || w='' + } + $1 $w -t nat -N $3 + #防回环 + $1 $w -t nat -A $3 -m mark --mark $routing_mark -j RETURN + [ "$2" = 'OUTPUT' ] && for gid in 453 7890; do + $1 $w -t nat -A $3 -m owner --gid-owner $gid -j RETURN + done + [ "$firewall_area" = 5 ] && { + $1 $w -t nat -A $3 -p tcp -s $bypass_host -j RETURN + $1 $w -t nat -A $3 -p udp -s $bypass_host -j RETURN + } + #局域网mac地址黑名单过滤 + [ "$2" = 'PREROUTING' ] && [ "$macfilter_type" != "白名单" ] && { + [ -s "$CRASHDIR"/configs/mac ] && + for mac in $(cat "$CRASHDIR"/configs/mac); do + $1 $w -t nat -A $3 -m mac --mac-source $mac -j RETURN + done + [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && + for ip in $(cat "$CRASHDIR"/configs/ip_filter); do + $1 $w -t nat -A $3 -s $ip -j RETURN + done + } + if [ "$2" = 'PREROUTING' ] && [ "$3" != 'shellcrash_vm_dns' ] && [ "$macfilter_type" = "白名单" ] && [ -n "$(cat $CRASHDIR/configs/mac $CRASHDIR/configs/ip_filter 2>/dev/null)" ]; then + [ -s "$CRASHDIR"/configs/mac ] && + for mac in $(cat "$CRASHDIR"/configs/mac); do + $1 $w -t nat -A $3 -p tcp -m mac --mac-source $mac -j REDIRECT --to-ports $dns_port + $1 $w -t nat -A $3 -p udp -m mac --mac-source $mac -j REDIRECT --to-ports $dns_port + done + [ -s "$CRASHDIR"/configs/ip_filter ] && [ "$1" = 'iptables' ] && + for ip in $(cat "$CRASHDIR"/configs/ip_filter); do + $1 $w -t nat -A $3 -p tcp -s $ip -j REDIRECT --to-ports $dns_port + $1 $w -t nat -A $3 -p udp -s $ip -j REDIRECT --to-ports $dns_port + done + else + for ip in $HOST_IP; do #仅限指定网段流量 + $1 $w -t nat -A $3 -p tcp -s $ip -j REDIRECT --to-ports $dns_port + $1 $w -t nat -A $3 -p udp -s $ip -j REDIRECT --to-ports $dns_port + done + fi + [ "$1" = 'ip6tables' ] && { #屏蔽外部请求 + $1 $w -t nat -A $3 -p tcp -j RETURN + $1 $w -t nat -A $3 -p udp -j RETURN + } + $1 $w -t nat -I $2 -p tcp --dport 53 -j $3 + $1 $w -t nat -I $2 -p udp --dport 53 -j $3 } start_ipt_wan() { #iptables公网防火墙 - #获取局域网host地址 - getlanip - if [ "$public_support" = "已开启" ]; then - $iptable -I INPUT -p tcp --dport $db_port -j ACCEPT - ckcmd ip6tables && $ip6table -I INPUT -p tcp --dport $db_port -j ACCEPT - else - #仅允许非公网设备访问面板 - for ip in $reserve_ipv4; do - $iptable -A INPUT -p tcp -s $ip --dport $db_port -j ACCEPT - done - $iptable -A INPUT -p tcp --dport $db_port -j REJECT - ckcmd ip6tables && $ip6table -A INPUT -p tcp --dport $db_port -j REJECT - fi - if [ "$public_mixport" = "已开启" ]; then - $iptable -I INPUT -p tcp --dport $mix_port -j ACCEPT - ckcmd ip6tables && $ip6table -I INPUT -p tcp --dport $mix_port -j ACCEPT - else - #仅允许局域网设备访问混合端口 - for ip in $reserve_ipv4; do - $iptable -A INPUT -p tcp -s $ip --dport $mix_port -j ACCEPT - done - $iptable -A INPUT -p tcp --dport $mix_port -j REJECT - ckcmd ip6tables && $ip6table -A INPUT -p tcp --dport $mix_port -j REJECT - fi - $iptable -I INPUT -p tcp -d 127.0.0.1 -j ACCEPT #本机请求全放行 + #获取局域网host地址 + getlanip + if [ "$public_support" = "已开启" ]; then + $iptable -I INPUT -p tcp --dport $db_port -j ACCEPT + ckcmd ip6tables && $ip6table -I INPUT -p tcp --dport $db_port -j ACCEPT + else + #仅允许非公网设备访问面板 + for ip in $reserve_ipv4; do + $iptable -A INPUT -p tcp -s $ip --dport $db_port -j ACCEPT + done + $iptable -A INPUT -p tcp --dport $db_port -j REJECT + ckcmd ip6tables && $ip6table -A INPUT -p tcp --dport $db_port -j REJECT + fi + if [ "$public_mixport" = "已开启" ]; then + $iptable -I INPUT -p tcp --dport $mix_port -j ACCEPT + ckcmd ip6tables && $ip6table -I INPUT -p tcp --dport $mix_port -j ACCEPT + else + #仅允许局域网设备访问混合端口 + for ip in $reserve_ipv4; do + $iptable -A INPUT -p tcp -s $ip --dport $mix_port -j ACCEPT + done + $iptable -A INPUT -p tcp --dport $mix_port -j REJECT + ckcmd ip6tables && $ip6table -A INPUT -p tcp --dport $mix_port -j REJECT + fi + $iptable -I INPUT -p tcp -d 127.0.0.1 -j ACCEPT #本机请求全放行 } start_iptables() { #iptables配置总入口 - #启动公网访问防火墙 - start_ipt_wan - #分模式设置流量劫持 - [ "$redir_mod" = "Redir模式" -o "$redir_mod" = "混合模式" ] && { - JUMP="REDIRECT --to-ports $redir_port" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && { - start_ipt_route iptables nat PREROUTING shellcrash tcp #ipv4-局域网tcp转发 - [ "$ipv6_redir" = "已开启" ] && { - if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then - start_ipt_route ip6tables nat PREROUTING shellcrashv6 tcp #ipv6-局域网tcp转发 - else - logger "当前设备内核缺少ip6tables_REDIRECT模块支持,已放弃启动相关规则!" 31 - fi - } - } - [ "$local_proxy" = true ] && { - start_ipt_route iptables nat OUTPUT shellcrash_out tcp #ipv4-本机tcp转发 - [ "$ipv6_redir" = "已开启" ] && { - if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then - start_ipt_route ip6tables nat OUTPUT shellcrashv6_out tcp #ipv6-本机tcp转发 - else - logger "当前设备内核缺少ip6tables_REDIRECT模块支持,已放弃启动相关规则!" 31 - fi - } - } - } - [ "$redir_mod" = "Tproxy模式" ] && { - modprobe xt_TPROXY >/dev/null 2>&1 - JUMP="TPROXY --on-port $tproxy_port --tproxy-mark $fwmark" #跳转劫持的具体命令 - if $iptable -j TPROXY -h 2>/dev/null | grep -q '\--on-port'; then - [ "$lan_proxy" = true ] && start_ipt_route iptables mangle PREROUTING shellcrash_mark all - [ "$local_proxy" = true ] && { - if [ -n "$(grep -E '^MARK$' /proc/net/ip_tables_targets)" ]; then - JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 - start_ipt_route iptables mangle OUTPUT shellcrash_mark_out all - $iptable -t mangle -A PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port - $iptable -t mangle -A PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port - else - logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动本机代理相关规则!" 31 - fi - } - else - logger "当前设备内核可能缺少kmod_ipt_tproxy模块支持,已放弃启动相关规则!" 31 - fi - [ "$ipv6_redir" = "已开启" ] && { - if $ip6table -j TPROXY -h 2>/dev/null | grep -q '\--on-port'; then - JUMP="TPROXY --on-port $tproxy_port --tproxy-mark $fwmark" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && start_ipt_route ip6tables mangle PREROUTING shellcrashv6_mark all - [ "$local_proxy" = true ] && { - if [ -n "$(grep -E '^MARK$' /proc/net/ip6_tables_targets)" ]; then - JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 - start_ipt_route ip6tables mangle OUTPUT shellcrashv6_mark_out all - $ip6table -t mangle -A PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port - $ip6table -t mangle -A PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port - else - logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动本机代理相关规则!" 31 - fi - } - else - logger "当前设备内核可能缺少kmod_ipt_tproxy或者xt_mark模块支持,已放弃启动相关规则!" 31 - fi - } - } - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" -o "$redir_mod" = "T&U旁路转发" -o "$redir_mod" = "TCP旁路转发" ] && { - JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "T&U旁路转发" ] && protocol=all - [ "$redir_mod" = "混合模式" ] && protocol=udp - [ "$redir_mod" = "TCP旁路转发" ] && protocol=tcp - if $iptable -j MARK -h 2>/dev/null | grep -q '\--set-mark'; then - [ "$lan_proxy" = true ] && { - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && $iptable -I FORWARD -o utun -j ACCEPT - start_ipt_route iptables mangle PREROUTING shellcrash_mark $protocol - } - [ "$local_proxy" = true ] && start_ipt_route iptables mangle OUTPUT shellcrash_mark_out $protocol - else - logger "当前设备内核可能缺少x_mark模块支持,已放弃启动相关规则!" 31 - fi - [ "$ipv6_redir" = "已开启" ] && [ "$crashcore" != clashpre ] && { - if $ip6table -j MARK -h 2>/dev/null | grep -q '\--set-mark'; then - [ "$lan_proxy" = true ] && { - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && $ip6table -I FORWARD -o utun -j ACCEPT - start_ipt_route ip6tables mangle PREROUTING shellcrashv6_mark $protocol - } - [ "$local_proxy" = true ] && start_ipt_route ip6tables mangle OUTPUT shellcrashv6_mark_out $protocol - else - logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动相关规则!" 31 - fi - } - } - [ "$vm_redir" = "已开启" ] && [ -n "$$vm_ipv4" ] && { - JUMP="REDIRECT --to-ports $redir_port" #跳转劫持的具体命令 - start_ipt_dns iptables PREROUTING shellcrash_vm_dns #ipv4-局域网dns转发 - start_ipt_route iptables nat PREROUTING shellcrash_vm tcp #ipv4-局域网tcp转发 - } - #启动DNS劫持 - [ "$dns_no" != "已禁用" -a "$dns_redir" != "已开启" -a "$firewall_area" -le 3 ] && { - [ "$lan_proxy" = true ] && { - start_ipt_dns iptables PREROUTING shellcrash_dns #ipv4-局域网dns转发 - if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then - start_ipt_dns ip6tables PREROUTING shellcrashv6_dns #ipv6-局域网dns转发 - else - $ip6table -I INPUT -p tcp --dport 53 -j REJECT >/dev/null 2>&1 - $ip6table -I INPUT -p udp --dport 53 -j REJECT >/dev/null 2>&1 - fi - } - [ "$local_proxy" = true ] && start_ipt_dns iptables OUTPUT shellcrash_dns_out #ipv4-本机dns转发 - } - #屏蔽QUIC - [ "$quic_rj" = '已启用' -a "$lan_proxy" = true -a "$redir_mod" != "Redir模式" ] && { - [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && { - set_cn_ip='-m set ! --match-set cn_ip dst' - set_cn_ip6='-m set ! --match-set cn_ip6 dst' - } - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { - $iptable -I FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT >/dev/null 2>&1 - $ip6table -I FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT >/dev/null 2>&1 - } - [ "$redir_mod" = "Tproxy模式" ] && { - $iptable -I INPUT -p udp --dport 443 $set_cn_ip -j REJECT >/dev/null 2>&1 - $ip6table -I INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT >/dev/null 2>&1 - } - } + #启动公网访问防火墙 + start_ipt_wan + #分模式设置流量劫持 + [ "$redir_mod" = "Redir模式" -o "$redir_mod" = "混合模式" ] && { + JUMP="REDIRECT --to-ports $redir_port" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && { + start_ipt_route iptables nat PREROUTING shellcrash tcp #ipv4-局域网tcp转发 + [ "$ipv6_redir" = "已开启" ] && { + if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then + start_ipt_route ip6tables nat PREROUTING shellcrashv6 tcp #ipv6-局域网tcp转发 + else + logger "当前设备内核缺少ip6tables_REDIRECT模块支持,已放弃启动相关规则!" 31 + fi + } + } + [ "$local_proxy" = true ] && { + start_ipt_route iptables nat OUTPUT shellcrash_out tcp #ipv4-本机tcp转发 + [ "$ipv6_redir" = "已开启" ] && { + if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then + start_ipt_route ip6tables nat OUTPUT shellcrashv6_out tcp #ipv6-本机tcp转发 + else + logger "当前设备内核缺少ip6tables_REDIRECT模块支持,已放弃启动相关规则!" 31 + fi + } + } + } + [ "$redir_mod" = "Tproxy模式" ] && { + modprobe xt_TPROXY >/dev/null 2>&1 + JUMP="TPROXY --on-port $tproxy_port --tproxy-mark $fwmark" #跳转劫持的具体命令 + if $iptable -j TPROXY -h 2>/dev/null | grep -q '\--on-port'; then + [ "$lan_proxy" = true ] && start_ipt_route iptables mangle PREROUTING shellcrash_mark all + [ "$local_proxy" = true ] && { + if [ -n "$(grep -E '^MARK$' /proc/net/ip_tables_targets)" ]; then + JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 + start_ipt_route iptables mangle OUTPUT shellcrash_mark_out all + $iptable -t mangle -A PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port + $iptable -t mangle -A PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port + else + logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动本机代理相关规则!" 31 + fi + } + else + logger "当前设备内核可能缺少kmod_ipt_tproxy模块支持,已放弃启动相关规则!" 31 + fi + [ "$ipv6_redir" = "已开启" ] && { + if $ip6table -j TPROXY -h 2>/dev/null | grep -q '\--on-port'; then + JUMP="TPROXY --on-port $tproxy_port --tproxy-mark $fwmark" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && start_ipt_route ip6tables mangle PREROUTING shellcrashv6_mark all + [ "$local_proxy" = true ] && { + if [ -n "$(grep -E '^MARK$' /proc/net/ip6_tables_targets)" ]; then + JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 + start_ipt_route ip6tables mangle OUTPUT shellcrashv6_mark_out all + $ip6table -t mangle -A PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port + $ip6table -t mangle -A PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port + else + logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动本机代理相关规则!" 31 + fi + } + else + logger "当前设备内核可能缺少kmod_ipt_tproxy或者xt_mark模块支持,已放弃启动相关规则!" 31 + fi + } + } + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" -o "$redir_mod" = "T&U旁路转发" -o "$redir_mod" = "TCP旁路转发" ] && { + JUMP="MARK --set-mark $fwmark" #跳转劫持的具体命令 + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "T&U旁路转发" ] && protocol=all + [ "$redir_mod" = "混合模式" ] && protocol=udp + [ "$redir_mod" = "TCP旁路转发" ] && protocol=tcp + if $iptable -j MARK -h 2>/dev/null | grep -q '\--set-mark'; then + [ "$lan_proxy" = true ] && { + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && $iptable -I FORWARD -o utun -j ACCEPT + start_ipt_route iptables mangle PREROUTING shellcrash_mark $protocol + } + [ "$local_proxy" = true ] && start_ipt_route iptables mangle OUTPUT shellcrash_mark_out $protocol + else + logger "当前设备内核可能缺少x_mark模块支持,已放弃启动相关规则!" 31 + fi + [ "$ipv6_redir" = "已开启" ] && [ "$crashcore" != clashpre ] && { + if $ip6table -j MARK -h 2>/dev/null | grep -q '\--set-mark'; then + [ "$lan_proxy" = true ] && { + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && $ip6table -I FORWARD -o utun -j ACCEPT + start_ipt_route ip6tables mangle PREROUTING shellcrashv6_mark $protocol + } + [ "$local_proxy" = true ] && start_ipt_route ip6tables mangle OUTPUT shellcrashv6_mark_out $protocol + else + logger "当前设备内核可能缺少xt_mark模块支持,已放弃启动相关规则!" 31 + fi + } + } + [ "$vm_redir" = "已开启" ] && [ -n "$$vm_ipv4" ] && { + JUMP="REDIRECT --to-ports $redir_port" #跳转劫持的具体命令 + start_ipt_dns iptables PREROUTING shellcrash_vm_dns #ipv4-局域网dns转发 + start_ipt_route iptables nat PREROUTING shellcrash_vm tcp #ipv4-局域网tcp转发 + } + #启动DNS劫持 + [ "$dns_no" != "已禁用" -a "$dns_redir" != "已开启" -a "$firewall_area" -le 3 ] && { + [ "$lan_proxy" = true ] && { + start_ipt_dns iptables PREROUTING shellcrash_dns #ipv4-局域网dns转发 + if $ip6table -j REDIRECT -h 2>/dev/null | grep -q '\--to-ports'; then + start_ipt_dns ip6tables PREROUTING shellcrashv6_dns #ipv6-局域网dns转发 + else + $ip6table -I INPUT -p tcp --dport 53 -j REJECT >/dev/null 2>&1 + $ip6table -I INPUT -p udp --dport 53 -j REJECT >/dev/null 2>&1 + fi + } + [ "$local_proxy" = true ] && start_ipt_dns iptables OUTPUT shellcrash_dns_out #ipv4-本机dns转发 + } + #屏蔽QUIC + [ "$quic_rj" = '已启用' -a "$lan_proxy" = true -a "$redir_mod" != "Redir模式" ] && { + [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && { + set_cn_ip='-m set ! --match-set cn_ip dst' + set_cn_ip6='-m set ! --match-set cn_ip6 dst' + } + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { + $iptable -I FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT >/dev/null 2>&1 + $ip6table -I FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT >/dev/null 2>&1 + } + [ "$redir_mod" = "Tproxy模式" ] && { + $iptable -I INPUT -p udp --dport 443 $set_cn_ip -j REJECT >/dev/null 2>&1 + $ip6table -I INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT >/dev/null 2>&1 + } + } } start_nft_route() { #nftables-route通用工具 - #$1:name $2:hook(prerouting/output) $3:type(nat/mangle/filter) $4:priority(-100/-150) - [ "$common_ports" = "已开启" ] && PORTS=$(echo $multiport | sed 's/,/, /g') - RESERVED_IP=$(echo $reserve_ipv4 | sed 's/ /, /g') - HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') - [ "$1" = 'output' ] && HOST_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')" - [ "$1" = 'prerouting_vm' ] && HOST_IP="$(echo $vm_ipv4 | sed 's/ /, /g')" - #添加新链 - nft add chain inet shellcrash $1 { type $3 hook $2 priority $4 \; } - [ "$1" = 'prerouting_vm' ] && nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理虚拟机流量 - #过滤dns - nft add rule inet shellcrash $1 tcp dport 53 return - nft add rule inet shellcrash $1 udp dport 53 return - #防回环 - nft add rule inet shellcrash $1 meta mark $routing_mark return - nft add rule inet shellcrash $1 meta skgid 7890 return - [ "$firewall_area" = 5 ] && nft add rule inet shellcrash $1 ip saddr $bypass_host return - [ -z "$ports" ] && nft add rule inet shellcrash $1 tcp dport {"$mix_port, $redir_port, $tproxy_port"} return - #过滤常用端口 - [ -n "$PORTS" ] && { - nft add rule inet shellcrash $1 ip daddr != {28.0.0.1/8} tcp dport != {$PORTS} return - nft add rule inet shellcrash $1 ip6 daddr != {fc00::/16} tcp dport != {$PORTS} return - } - #nft add rule inet shellcrash $1 ip saddr 28.0.0.1/8 return - nft add rule inet shellcrash $1 ip daddr {$RESERVED_IP} return #过滤保留地址 - #过滤局域网设备 - [ "$1" = 'prerouting' ] && { - [ "$macfilter_type" != "白名单" ] && { - [ -s "$CRASHDIR"/configs/mac ] && { - MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) - nft add rule inet shellcrash $1 ether saddr {$MAC} return - } - [ -s "$CRASHDIR"/configs/ip_filter ] && { - FL_IP=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/ip_filter) - nft add rule inet shellcrash $1 ip saddr {$FL_IP} return - } - nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理本机局域网网段流量 - } - [ "$macfilter_type" = "白名单" ] && { - [ -s "$CRASHDIR"/configs/mac ] && MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) - [ -s "$CRASHDIR"/configs/ip_filter ] && FL_IP=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/ip_filter) - if [ -n "$MAC" ] && [ -n "$FL_IP" ]; then - nft add rule inet shellcrash $1 ether saddr != {$MAC} ip saddr != {$FL_IP} return - elif [ -n "$MAC" ]; then - nft add rule inet shellcrash $1 ether saddr != {$MAC} return - elif [ -n "$FL_IP" ]; then - nft add rule inet shellcrash $1 ip saddr != {$FL_IP} return - else - nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理本机局域网网段流量 - fi - } - } - #绕过CN-IP - [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" -a -f "$BINDIR"/cn_ip.txt ] && { - CN_IP=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ip.txt) - [ -n "$CN_IP" ] && nft add rule inet shellcrash $1 ip daddr {$CN_IP} return - } - #局域网ipv6支持 - if [ "$ipv6_redir" = "已开启" -a "$1" = 'prerouting' -a "$firewall_area" != 5 ]; then - RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')" - HOST_IP6="$(echo $host_ipv6 | sed 's/ /, /g')" - #过滤保留地址及本机地址 - nft add rule inet shellcrash $1 ip6 daddr {$RESERVED_IP6} return - #仅代理本机局域网网段流量 - nft add rule inet shellcrash $1 ip6 saddr != {$HOST_IP6} return - #绕过CN_IPV6 - [ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f "$BINDIR"/cn_ipv6.txt ] && { - CN_IP6=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ipv6.txt) - [ -n "$CN_IP6" ] && nft add rule inet shellcrash $1 ip6 daddr {$CN_IP6} return - } - elif [ "$ipv6_redir" = "已开启" -a "$1" = 'output' -a \( "$firewall_area" = 2 -o "$firewall_area" = 3 \) ]; then - RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')" - HOST_IP6="::1, $(echo $host_ipv6 | sed 's/ /, /g')" - #过滤保留地址及本机地址 - nft add rule inet shellcrash $1 ip6 daddr {$RESERVED_IP6} return - #仅代理本机局域网网段流量 - nft add rule inet shellcrash $1 ip6 saddr != {$HOST_IP6} return - #绕过CN_IPV6 - [ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f "$BINDIR"/cn_ipv6.txt ] && { - CN_IP6=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ipv6.txt) - [ -n "$CN_IP6" ] && nft add rule inet shellcrash $1 ip6 daddr {$CN_IP6} return - } - else - nft add rule inet shellcrash $1 meta nfproto ipv6 return - fi - #添加通用路由 - nft add rule inet shellcrash "$1" "$JUMP" - #处理特殊路由 - [ "$redir_mod" = "混合模式" ] && { - nft add rule inet shellcrash $1 meta l4proto tcp mark set $((fwmark + 1)) - nft add chain inet shellcrash "$1"_mixtcp { type nat hook $2 priority -100 \; } - nft add rule inet shellcrash "$1"_mixtcp mark $((fwmark + 1)) meta l4proto tcp redirect to $redir_port - } - #nft add rule inet shellcrash local_tproxy log prefix \"pre\" level debug + #$1:name $2:hook(prerouting/output) $3:type(nat/mangle/filter) $4:priority(-100/-150) + [ "$common_ports" = "已开启" ] && PORTS=$(echo $multiport | sed 's/,/, /g') + RESERVED_IP=$(echo $reserve_ipv4 | sed 's/ /, /g') + HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') + [ "$1" = 'output' ] && HOST_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')" + [ "$1" = 'prerouting_vm' ] && HOST_IP="$(echo $vm_ipv4 | sed 's/ /, /g')" + #添加新链 + nft add chain inet shellcrash $1 { type $3 hook $2 priority $4 \; } + [ "$1" = 'prerouting_vm' ] && nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理虚拟机流量 + #过滤dns + nft add rule inet shellcrash $1 tcp dport 53 return + nft add rule inet shellcrash $1 udp dport 53 return + #防回环 + nft add rule inet shellcrash $1 meta mark $routing_mark return + nft add rule inet shellcrash $1 meta skgid 7890 return + [ "$firewall_area" = 5 ] && nft add rule inet shellcrash $1 ip saddr $bypass_host return + [ -z "$ports" ] && nft add rule inet shellcrash $1 tcp dport {"$mix_port, $redir_port, $tproxy_port"} return + #过滤常用端口 + [ -n "$PORTS" ] && { + nft add rule inet shellcrash $1 ip daddr != {28.0.0.1/8} tcp dport != {$PORTS} return + nft add rule inet shellcrash $1 ip6 daddr != {fc00::/16} tcp dport != {$PORTS} return + } + #nft add rule inet shellcrash $1 ip saddr 28.0.0.1/8 return + nft add rule inet shellcrash $1 ip daddr {$RESERVED_IP} return #过滤保留地址 + #过滤局域网设备 + [ "$1" = 'prerouting' ] && { + [ "$macfilter_type" != "白名单" ] && { + [ -s "$CRASHDIR"/configs/mac ] && { + MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) + nft add rule inet shellcrash $1 ether saddr {$MAC} return + } + [ -s "$CRASHDIR"/configs/ip_filter ] && { + FL_IP=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/ip_filter) + nft add rule inet shellcrash $1 ip saddr {$FL_IP} return + } + nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理本机局域网网段流量 + } + [ "$macfilter_type" = "白名单" ] && { + [ -s "$CRASHDIR"/configs/mac ] && MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) + [ -s "$CRASHDIR"/configs/ip_filter ] && FL_IP=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/ip_filter) + if [ -n "$MAC" ] && [ -n "$FL_IP" ]; then + nft add rule inet shellcrash $1 ether saddr != {$MAC} ip saddr != {$FL_IP} return + elif [ -n "$MAC" ]; then + nft add rule inet shellcrash $1 ether saddr != {$MAC} return + elif [ -n "$FL_IP" ]; then + nft add rule inet shellcrash $1 ip saddr != {$FL_IP} return + else + nft add rule inet shellcrash $1 ip saddr != {$HOST_IP} return #仅代理本机局域网网段流量 + fi + } + } + #绕过CN-IP + [ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" -a -f "$BINDIR"/cn_ip.txt ] && { + CN_IP=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ip.txt) + [ -n "$CN_IP" ] && nft add rule inet shellcrash $1 ip daddr {$CN_IP} return + } + #局域网ipv6支持 + if [ "$ipv6_redir" = "已开启" -a "$1" = 'prerouting' -a "$firewall_area" != 5 ]; then + RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')" + HOST_IP6="$(echo $host_ipv6 | sed 's/ /, /g')" + #过滤保留地址及本机地址 + nft add rule inet shellcrash $1 ip6 daddr {$RESERVED_IP6} return + #仅代理本机局域网网段流量 + nft add rule inet shellcrash $1 ip6 saddr != {$HOST_IP6} return + #绕过CN_IPV6 + [ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f "$BINDIR"/cn_ipv6.txt ] && { + CN_IP6=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ipv6.txt) + [ -n "$CN_IP6" ] && nft add rule inet shellcrash $1 ip6 daddr {$CN_IP6} return + } + elif [ "$ipv6_redir" = "已开启" -a "$1" = 'output' -a \( "$firewall_area" = 2 -o "$firewall_area" = 3 \) ]; then + RESERVED_IP6="$(echo "$reserve_ipv6 $host_ipv6" | sed 's/ /, /g')" + HOST_IP6="::1, $(echo $host_ipv6 | sed 's/ /, /g')" + #过滤保留地址及本机地址 + nft add rule inet shellcrash $1 ip6 daddr {$RESERVED_IP6} return + #仅代理本机局域网网段流量 + nft add rule inet shellcrash $1 ip6 saddr != {$HOST_IP6} return + #绕过CN_IPV6 + [ "$dns_mod" != "fake-ip" -a "$cn_ipv6_route" = "已开启" -a -f "$BINDIR"/cn_ipv6.txt ] && { + CN_IP6=$(awk '{printf "%s, ",$1}' "$BINDIR"/cn_ipv6.txt) + [ -n "$CN_IP6" ] && nft add rule inet shellcrash $1 ip6 daddr {$CN_IP6} return + } + else + nft add rule inet shellcrash $1 meta nfproto ipv6 return + fi + #添加通用路由 + nft add rule inet shellcrash "$1" "$JUMP" + #处理特殊路由 + [ "$redir_mod" = "混合模式" ] && { + nft add rule inet shellcrash $1 meta l4proto tcp mark set $((fwmark + 1)) + nft add chain inet shellcrash "$1"_mixtcp { type nat hook $2 priority -100 \; } + nft add rule inet shellcrash "$1"_mixtcp mark $((fwmark + 1)) meta l4proto tcp redirect to $redir_port + } + #nft add rule inet shellcrash local_tproxy log prefix \"pre\" level debug } start_nft_dns() { #nftables-dns - HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') - HOST_IP6=$(echo $host_ipv6 | sed 's/ /, /g') - [ "$1" = 'output' ] && HOST_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')" - [ "$1" = 'prerouting_vm' ] && HOST_IP="$(echo $vm_ipv4 | sed 's/ /, /g')" - nft add chain inet shellcrash "$1"_dns { type nat hook $2 priority -100 \; } - #过滤非dns请求 - nft add rule inet shellcrash "$1"_dns udp dport != 53 return - nft add rule inet shellcrash "$1"_dns tcp dport != 53 return - #防回环 - nft add rule inet shellcrash "$1"_dns meta mark $routing_mark return - nft add rule inet shellcrash "$1"_dns meta skgid { 453, 7890 } return - [ "$firewall_area" = 5 ] && nft add rule inet shellcrash "$1"_dns ip saddr $bypass_host return - nft add rule inet shellcrash "$1"_dns ip saddr != {$HOST_IP} return #屏蔽外部请求 - [ "$1" = 'prerouting' ] && nft add rule inet shellcrash "$1"_dns ip6 saddr != {$HOST_IP6} return #屏蔽外部请求 - #过滤局域网设备 - [ "$1" = 'prerouting' ] && [ -s "$CRASHDIR"/configs/mac ] && { - MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) - if [ "$macfilter_type" = "黑名单" ]; then - nft add rule inet shellcrash "$1"_dns ether saddr {$MAC} return - else - nft add rule inet shellcrash "$1"_dns ether saddr != {$MAC} return - fi - } - nft add rule inet shellcrash "$1"_dns udp dport 53 redirect to ${dns_port} - nft add rule inet shellcrash "$1"_dns tcp dport 53 redirect to ${dns_port} + HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') + HOST_IP6=$(echo $host_ipv6 | sed 's/ /, /g') + [ "$1" = 'output' ] && HOST_IP="127.0.0.0/8, $(echo $local_ipv4 | sed 's/ /, /g')" + [ "$1" = 'prerouting_vm' ] && HOST_IP="$(echo $vm_ipv4 | sed 's/ /, /g')" + nft add chain inet shellcrash "$1"_dns { type nat hook $2 priority -100 \; } + #过滤非dns请求 + nft add rule inet shellcrash "$1"_dns udp dport != 53 return + nft add rule inet shellcrash "$1"_dns tcp dport != 53 return + #防回环 + nft add rule inet shellcrash "$1"_dns meta mark $routing_mark return + nft add rule inet shellcrash "$1"_dns meta skgid { 453, 7890 } return + [ "$firewall_area" = 5 ] && nft add rule inet shellcrash "$1"_dns ip saddr $bypass_host return + nft add rule inet shellcrash "$1"_dns ip saddr != {$HOST_IP} return #屏蔽外部请求 + [ "$1" = 'prerouting' ] && nft add rule inet shellcrash "$1"_dns ip6 saddr != {$HOST_IP6} return #屏蔽外部请求 + #过滤局域网设备 + [ "$1" = 'prerouting' ] && [ -s "$CRASHDIR"/configs/mac ] && { + MAC=$(awk '{printf "%s, ",$1}' "$CRASHDIR"/configs/mac) + if [ "$macfilter_type" = "黑名单" ]; then + nft add rule inet shellcrash "$1"_dns ether saddr {$MAC} return + else + nft add rule inet shellcrash "$1"_dns ether saddr != {$MAC} return + fi + } + nft add rule inet shellcrash "$1"_dns udp dport 53 redirect to ${dns_port} + nft add rule inet shellcrash "$1"_dns tcp dport 53 redirect to ${dns_port} } start_nft_wan() { #nftables公网防火墙 - #获取局域网host地址 - getlanip - HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') - nft add chain inet shellcrash input { type filter hook input priority -100 \; } - nft add rule inet shellcrash input ip daddr 127.0.0.1 accept - if [ "$public_support" = "已开启" ]; then - nft add rule inet shellcrash input tcp dport $db_port accept - else - #仅允许非公网设备访问面板 - nft add rule inet shellcrash input tcp dport $db_port ip saddr {$HOST_IP} accept - nft add rule inet shellcrash input tcp dport $db_port reject - fi - if [ "$public_mixport" = "已开启" ]; then - nft add rule inet shellcrash input tcp dport $mix_port accept - else - #仅允许局域网设备访问混合端口 - nft add rule inet shellcrash input tcp dport $mix_port ip saddr {$HOST_IP} accept - nft add rule inet shellcrash input tcp dport $mix_port reject - fi + #获取局域网host地址 + getlanip + HOST_IP=$(echo $host_ipv4 | sed 's/ /, /g') + nft add chain inet shellcrash input { type filter hook input priority -100 \; } + nft add rule inet shellcrash input ip daddr 127.0.0.1 accept + if [ "$public_support" = "已开启" ]; then + nft add rule inet shellcrash input tcp dport $db_port accept + else + #仅允许非公网设备访问面板 + nft add rule inet shellcrash input tcp dport $db_port ip saddr {$HOST_IP} accept + nft add rule inet shellcrash input tcp dport $db_port reject + fi + if [ "$public_mixport" = "已开启" ]; then + nft add rule inet shellcrash input tcp dport $mix_port accept + else + #仅允许局域网设备访问混合端口 + nft add rule inet shellcrash input tcp dport $mix_port ip saddr {$HOST_IP} accept + nft add rule inet shellcrash input tcp dport $mix_port reject + fi } start_nftables() { #nftables配置总入口 - #初始化nftables - nft add table inet shellcrash - nft flush table inet shellcrash - #公网访问防火墙 - start_nft_wan - #启动DNS劫持 - [ "$dns_no" != "已禁用" -a "$dns_redir" != "已开启" -a "$firewall_area" -le 3 ] && { - [ "$lan_proxy" = true ] && start_nft_dns prerouting prerouting #局域网dns转发 - [ "$local_proxy" = true ] && start_nft_dns output output #本机dns转发 - } - #分模式设置流量劫持 - [ "$redir_mod" = "Redir模式" ] && { - JUMP="meta l4proto tcp redirect to $redir_port" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting nat -100 - [ "$local_proxy" = true ] && start_nft_route output output nat -100 - } - [ "$redir_mod" = "Tproxy模式" ] && (modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy) && { - JUMP="meta l4proto {tcp, udp} mark set $fwmark tproxy to :$tproxy_port" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting filter -150 - [ "$local_proxy" = true ] && { - JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 - start_nft_route output output route -150 - nft add chain inet shellcrash mark_out { type filter hook prerouting priority -100 \; } - nft add rule inet shellcrash mark_out meta mark $fwmark meta l4proto {tcp, udp} tproxy to :$tproxy_port - } - } - [ "$tun_statu" = true ] && { - [ "$redir_mod" = "Tun模式" ] && JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 - [ "$redir_mod" = "混合模式" ] && JUMP="meta l4proto udp mark set $fwmark" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && { - start_nft_route prerouting prerouting filter -150 - #放行流量 - nft list table inet fw4 >/dev/null 2>&1 || nft add table inet fw4 - nft list chain inet fw4 forward >/dev/null 2>&1 || nft add chain inet fw4 forward { type filter hook forward priority filter \; } 2>/dev/null - nft list chain inet fw4 input >/dev/null 2>&1 || nft add chain inet fw4 input { type filter hook input priority filter \; } 2>/dev/null - nft list chain inet fw4 forward | grep -q 'oifname "utun" accept' || nft insert rule inet fw4 forward oifname "utun" accept - nft list chain inet fw4 input | grep -q 'iifname "utun" accept' || nft insert rule inet fw4 input iifname "utun" accept - } - [ "$local_proxy" = true ] && start_nft_route output output route -150 - } - [ "$firewall_area" = 5 ] && { - [ "$redir_mod" = "T&U旁路转发" ] && JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 - [ "$redir_mod" = "TCP旁路转发" ] && JUMP="meta l4proto tcp mark set $fwmark" #跳转劫持的具体命令 - [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting filter -150 - [ "$local_proxy" = true ] && start_nft_route output output route -150 - } - [ "$vm_redir" = "已开启" ] && [ -n "$$vm_ipv4" ] && { - start_nft_dns prerouting_vm prerouting - JUMP="meta l4proto tcp redirect to $redir_port" #跳转劫持的具体命令 - start_nft_route prerouting_vm prerouting nat -100 - } - #屏蔽QUIC - [ "$quic_rj" = '已启用' -a "$lan_proxy" = true ] && { - [ "$redir_mod" = "Tproxy模式" ] && { - nft add chain inet shellcrash quic_rj { type filter hook input priority 0 \; } - [ -n "$CN_IP" ] && nft add rule inet shellcrash quic_rj ip daddr {$CN_IP} return - [ -n "$CN_IP6" ] && nft add rule inet shellcrash quic_rj ip6 daddr {$CN_IP6} return - nft add rule inet shellcrash quic_rj udp dport {443, 8443} reject comment 'ShellCrash-QUIC-REJECT' - } - [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { - nft insert rule inet fw4 forward oifname "utun" udp dport {443, 8443} reject comment 'ShellCrash-QUIC-REJECT' - [ -n "$CN_IP" ] && nft insert rule inet fw4 forward oifname "utun" ip daddr {$CN_IP} return - [ -n "$CN_IP6" ] && nft insert rule inet fw4 forward oifname "utun" ip6 daddr {$CN_IP6} return - } - } + #初始化nftables + nft add table inet shellcrash + nft flush table inet shellcrash + #公网访问防火墙 + start_nft_wan + #启动DNS劫持 + [ "$dns_no" != "已禁用" -a "$dns_redir" != "已开启" -a "$firewall_area" -le 3 ] && { + [ "$lan_proxy" = true ] && start_nft_dns prerouting prerouting #局域网dns转发 + [ "$local_proxy" = true ] && start_nft_dns output output #本机dns转发 + } + #分模式设置流量劫持 + [ "$redir_mod" = "Redir模式" ] && { + JUMP="meta l4proto tcp redirect to $redir_port" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting nat -100 + [ "$local_proxy" = true ] && start_nft_route output output nat -100 + } + [ "$redir_mod" = "Tproxy模式" ] && (modprobe nft_tproxy >/dev/null 2>&1 || lsmod 2>/dev/null | grep -q nft_tproxy) && { + JUMP="meta l4proto {tcp, udp} mark set $fwmark tproxy to :$tproxy_port" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting filter -150 + [ "$local_proxy" = true ] && { + JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 + start_nft_route output output route -150 + nft add chain inet shellcrash mark_out { type filter hook prerouting priority -100 \; } + nft add rule inet shellcrash mark_out meta mark $fwmark meta l4proto {tcp, udp} tproxy to :$tproxy_port + } + } + [ "$tun_statu" = true ] && { + [ "$redir_mod" = "Tun模式" ] && JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 + [ "$redir_mod" = "混合模式" ] && JUMP="meta l4proto udp mark set $fwmark" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && { + start_nft_route prerouting prerouting filter -150 + #放行流量 + nft list table inet fw4 >/dev/null 2>&1 || nft add table inet fw4 + nft list chain inet fw4 forward >/dev/null 2>&1 || nft add chain inet fw4 forward { type filter hook forward priority filter \; } 2>/dev/null + nft list chain inet fw4 input >/dev/null 2>&1 || nft add chain inet fw4 input { type filter hook input priority filter \; } 2>/dev/null + nft list chain inet fw4 forward | grep -q 'oifname "utun" accept' || nft insert rule inet fw4 forward oifname "utun" accept + nft list chain inet fw4 input | grep -q 'iifname "utun" accept' || nft insert rule inet fw4 input iifname "utun" accept + } + [ "$local_proxy" = true ] && start_nft_route output output route -150 + } + [ "$firewall_area" = 5 ] && { + [ "$redir_mod" = "T&U旁路转发" ] && JUMP="meta l4proto {tcp, udp} mark set $fwmark" #跳转劫持的具体命令 + [ "$redir_mod" = "TCP旁路转发" ] && JUMP="meta l4proto tcp mark set $fwmark" #跳转劫持的具体命令 + [ "$lan_proxy" = true ] && start_nft_route prerouting prerouting filter -150 + [ "$local_proxy" = true ] && start_nft_route output output route -150 + } + [ "$vm_redir" = "已开启" ] && [ -n "$$vm_ipv4" ] && { + start_nft_dns prerouting_vm prerouting + JUMP="meta l4proto tcp redirect to $redir_port" #跳转劫持的具体命令 + start_nft_route prerouting_vm prerouting nat -100 + } + #屏蔽QUIC + [ "$quic_rj" = '已启用' -a "$lan_proxy" = true ] && { + [ "$redir_mod" = "Tproxy模式" ] && { + nft add chain inet shellcrash quic_rj { type filter hook input priority 0 \; } + [ -n "$CN_IP" ] && nft add rule inet shellcrash quic_rj ip daddr {$CN_IP} return + [ -n "$CN_IP6" ] && nft add rule inet shellcrash quic_rj ip6 daddr {$CN_IP6} return + nft add rule inet shellcrash quic_rj udp dport {443, 8443} reject comment 'ShellCrash-QUIC-REJECT' + } + [ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && { + nft insert rule inet fw4 forward oifname "utun" udp dport {443, 8443} reject comment 'ShellCrash-QUIC-REJECT' + [ -n "$CN_IP" ] && nft insert rule inet fw4 forward oifname "utun" ip daddr {$CN_IP} return + [ -n "$CN_IP6" ] && nft insert rule inet fw4 forward oifname "utun" ip6 daddr {$CN_IP6} return + } + } } 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' ] && start_iptables - [ "$firewall_mod" = 'nftables' ] && start_nftables - #修复部分虚拟机dns查询失败的问题 - [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ -w /etc/resolv.conf ] && { - 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 - } - #openwrt使用dnsmasq转发DNS - if [ "$dns_redir" = "已开启" -a "$firewall_area" -le 3 -a "$dns_no" != "已禁用" ]; then - uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 - uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null - uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1 - uci set dhcp.@dnsmasq[0].noresolv=1 2>/dev/null - uci commit dhcp >/dev/null 2>&1 - /etc/init.d/dnsmasq restart >/dev/null 2>&1 - elif [ "$(uci get dhcp.@dnsmasq[0].dns_redirect 2>/dev/null)" = 1 ]; then - uci del dhcp.@dnsmasq[0].dns_redirect - uci commit dhcp.@dnsmasq[0] - fi + 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' ] && start_iptables + [ "$firewall_mod" = 'nftables' ] && start_nftables + #修复部分虚拟机dns查询失败的问题 + [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ -w /etc/resolv.conf ] && { + 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 + } + #openwrt使用dnsmasq转发DNS + if [ "$dns_redir" = "已开启" -a "$firewall_area" -le 3 -a "$dns_no" != "已禁用" ]; then + uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1 + uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null + uci add_list dhcp.@dnsmasq[0].server=127.0.0.1#$dns_port >/dev/null 2>&1 + uci set dhcp.@dnsmasq[0].noresolv=1 2>/dev/null + uci commit dhcp >/dev/null 2>&1 + /etc/init.d/dnsmasq restart >/dev/null 2>&1 + elif [ "$(uci get dhcp.@dnsmasq[0].dns_redirect 2>/dev/null)" = 1 ]; then + uci del dhcp.@dnsmasq[0].dns_redirect + uci commit dhcp.@dnsmasq[0] + fi } 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.1/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.1/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.1/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.1/8 -j shellcrash_mark 2>/dev/null - $iptable -t mangle -D PREROUTING -p udp -d 28.0.0.1/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.1/8 -j shellcrash_mark_out 2>/dev/null - $iptable -t mangle -D OUTPUT -p udp -d 28.0.0.1/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 - #公网访问 - for ip in $host_ipv4 $local_ipv4 $reserve_ipv4; do - $iptable -D INPUT -p tcp -s $ip --dport $mix_port -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp -s $ip --dport $db_port -j ACCEPT 2>/dev/null - done - $iptable -D INPUT -p tcp -d 127.0.0.1 -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp --dport $mix_port -j REJECT 2>/dev/null - $iptable -D INPUT -p tcp --dport $mix_port -j ACCEPT 2>/dev/null - $iptable -D INPUT -p tcp --dport $db_port -j REJECT 2>/dev/null - $iptable -D INPUT -p tcp --dport $db_port -j ACCEPT 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_ipv6_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 -p tcp --dport $mix_port -j REJECT 2>/dev/null - $ip6table -D INPUT -p tcp --dport $mix_port -j ACCEPT 2>/dev/null - $ip6table -D INPUT -p tcp --dport $db_port -j REJECT 2>/dev/null - $ip6table -D INPUT -p tcp --dport $db_port -j ACCEPT 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 - sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf + #获取局域网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.1/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.1/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.1/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.1/8 -j shellcrash_mark 2>/dev/null + $iptable -t mangle -D PREROUTING -p udp -d 28.0.0.1/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.1/8 -j shellcrash_mark_out 2>/dev/null + $iptable -t mangle -D OUTPUT -p udp -d 28.0.0.1/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 + #公网访问 + for ip in $host_ipv4 $local_ipv4 $reserve_ipv4; do + $iptable -D INPUT -p tcp -s $ip --dport $mix_port -j ACCEPT 2>/dev/null + $iptable -D INPUT -p tcp -s $ip --dport $db_port -j ACCEPT 2>/dev/null + done + $iptable -D INPUT -p tcp -d 127.0.0.1 -j ACCEPT 2>/dev/null + $iptable -D INPUT -p tcp --dport $mix_port -j REJECT 2>/dev/null + $iptable -D INPUT -p tcp --dport $mix_port -j ACCEPT 2>/dev/null + $iptable -D INPUT -p tcp --dport $db_port -j REJECT 2>/dev/null + $iptable -D INPUT -p tcp --dport $db_port -j ACCEPT 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_ipv6_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 -p tcp --dport $mix_port -j REJECT 2>/dev/null + $ip6table -D INPUT -p tcp --dport $mix_port -j ACCEPT 2>/dev/null + $ip6table -D INPUT -p tcp --dport $db_port -j REJECT 2>/dev/null + $ip6table -D INPUT -p tcp --dport $db_port -j ACCEPT 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 + sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf } #启动相关 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 + #使用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 - #} - } + #设置循环检测面板端口以判定服务启动是否成功 + 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 <"$BINDIR"/ui/index.html < @@ -1740,11 +1740,11 @@ makehtml() { #生成面板跳转文件 EOF } catpac() { #生成pac文件 - #获取本机host地址 - [ -n "$host" ] && host_pac=$host - [ -z "$host_pac" ] && host_pac=$(ubus call network.interface.lan status 2>&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}') - [ -z "$host_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 \"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_check() { #检查及下载内核文件 + [ -n "$(tar --help 2>&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 ----------------------------------------------- + #$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 + #检测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 + #检测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 dns.alidns.com doh.pub doh.360.cn; do - ping -c 3 $text >/dev/null 2>&1 && return 0 - sleep 5 - done - logger "当前设备无法连接网络,已停止启动!" 33 - exit 1 + for text in 223.5.5.5 dns.alidns.com doh.pub doh.360.cn; 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_ipv6_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 + 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_ipv6_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 - } & - else - start_error - $0 stop - fi + [ -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 + } & + 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 + 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() { #保守模式 - #使用传统后台执行二进制文件的方式执行 - if ckcmd su && [ -n "$(grep 'shellcrash:x:0:7890' /etc/passwd)" ]; then - su shellcrash -c "$COMMAND >/dev/null 2>&1" & - else - ckcmd nohup && local nohup=nohup - $nohup $COMMAND >/dev/null 2>&1 & - fi - afstart & + #使用传统后台执行二进制文件的方式执行 + if ckcmd su && [ -n "$(grep 'shellcrash:x:0:7890' /etc/passwd)" ]; then + su shellcrash -c "$COMMAND >/dev/null 2>&1" & + else + ckcmd nohup && local nohup=nohup + $nohup $COMMAND >/dev/null 2>&1 & + fi + afstart & } #杂项 update_config() { #更新订阅并重启 - get_core_config && - $0 restart + 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 + 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 } set_proxy() { #设置环境变量 - if [ "$local_type" = "环境变量" ]; then - [ -w ~/.bashrc ] && profile=~/.bashrc - [ -w /etc/profile ] && profile=/etc/profile - echo 'export all_proxy=http://127.0.0.1:'"$mix_port" >>$profile - echo 'export ALL_PROXY=$all_proxy' >>$profile - fi + if [ "$local_type" = "环境变量" ]; then + [ -w ~/.bashrc ] && profile=~/.bashrc + [ -w /etc/profile ] && profile=/etc/profile + echo 'export all_proxy=http://127.0.0.1:'"$mix_port" >>$profile + echo 'export ALL_PROXY=$all_proxy' >>$profile + fi } unset_proxy() { #卸载环境变量 - [ -w ~/.bashrc ] && profile=~/.bashrc - [ -w /etc/profile ] && profile=/etc/profile - sed -i '/all_proxy/'d $profile - sed -i '/ALL_PROXY/'d $profile + [ -w ~/.bashrc ] && profile=~/.bashrc + [ -w /etc/profile ] && profile=/etc/profile + sed -i '/all_proxy/'d $profile + sed -i '/ALL_PROXY/'d $profile } getconfig #读取配置及全局变量 @@ -2021,157 +2021,157 @@ getconfig #读取配置及全局变量 case "$1" in start) - [ -n "$(pidof CrashCore)" ] && $0 stop #禁止多实例 - stop_firewall #清理路由策略 - #使用不同方式启动服务 - if [ "$firewall_area" = "5" ]; then #主旁转发 - start_firewall - elif [ "$start_old" = "已开启" ]; then - bfstart && start_old - elif [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then - /etc/init.d/shellcrash start - elif [ "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then - bfstart && { - 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 - } - elif rc-status -r >/dev/null 2>&1; then - rc-service shellcrash stop >/dev/null 2>&1 - rc-service shellcrash start - else - bfstart && start_old - fi - if [ "$2" = "infinity" ]; then #增加容器自启方式,请将CMD设置为"$CRASHDIR"/start.sh start infinity - sleep infinity - fi - ;; + [ -n "$(pidof CrashCore)" ] && $0 stop #禁止多实例 + stop_firewall #清理路由策略 + #使用不同方式启动服务 + if [ "$firewall_area" = "5" ]; then #主旁转发 + start_firewall + elif [ "$start_old" = "已开启" ]; then + bfstart && start_old + elif [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then + /etc/init.d/shellcrash start + elif [ "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then + bfstart && { + 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 + } + elif rc-status -r >/dev/null 2>&1; then + rc-service shellcrash stop >/dev/null 2>&1 + rc-service shellcrash start + else + bfstart && start_old + fi + if [ "$2" = "infinity" ]; then #增加容器自启方式,请将CMD设置为"$CRASHDIR"/start.sh start infinity + sleep infinity + fi + ;; stop) - logger ShellCrash服务即将关闭…… - [ -n "$(pidof CrashCore)" ] && web_save #保存面板配置 - #删除守护进程&面板配置自动保存 - cronset '保守模式守护进程' - cronset '运行时每' - cronset '流媒体预解析' - #多种方式结束进程 + logger ShellCrash服务即将关闭…… + [ -n "$(pidof CrashCore)" ] && web_save #保存面板配置 + #删除守护进程&面板配置自动保存 + cronset '保守模式守护进程' + cronset '运行时每' + cronset '流媒体预解析' + #多种方式结束进程 - if [ "$start_old" != "已开启" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then - systemctl stop shellcrash.service >/dev/null 2>&1 - elif [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then - /etc/init.d/shellcrash stop >/dev/null 2>&1 - elif rc-status -r >/dev/null 2>&1; then - rc-service shellcrash stop >/dev/null 2>&1 - else - stop_firewall #清理路由策略 - unset_proxy #禁用本机代理 - fi - PID=$(pidof CrashCore) && [ -n "$PID" ] && kill -9 $PID >/dev/null 2>&1 - #清理缓存目录 - rm -rf "$TMPDIR"/CrashCore - ;; + if [ "$start_old" != "已开启" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then + systemctl stop shellcrash.service >/dev/null 2>&1 + elif [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then + /etc/init.d/shellcrash stop >/dev/null 2>&1 + elif rc-status -r >/dev/null 2>&1; then + rc-service shellcrash stop >/dev/null 2>&1 + else + stop_firewall #清理路由策略 + unset_proxy #禁用本机代理 + fi + PID=$(pidof CrashCore) && [ -n "$PID" ] && kill -9 $PID >/dev/null 2>&1 + #清理缓存目录 + rm -rf "$TMPDIR"/CrashCore + ;; restart) - $0 stop - $0 start - ;; + $0 stop + $0 start + ;; daemon) - if [ -f $TMPDIR/crash_start_time ]; then - $0 start - else - sleep 60 && touch $TMPDIR/crash_start_time - fi - ;; + if [ -f $TMPDIR/crash_start_time ]; then + $0 start + else + sleep 60 && touch $TMPDIR/crash_start_time + fi + ;; debug) - [ -n "$(pidof CrashCore)" ] && $0 stop >/dev/null #禁止多实例 - stop_firewall >/dev/null #清理路由策略 - bfstart - if [ -n "$2" ]; then - if echo "$crashcore" | grep -q 'singbox'; then - sed -i "s/\"level\": \"info\"/\"level\": \"$2\"/" "$TMPDIR"/jsons/log.json 2>/dev/null - else - sed -i "s/log-level: info/log-level: $2/" "$TMPDIR"/config.yaml - fi - [ "$3" = flash ] && dir=$CRASHDIR || dir=$TMPDIR - $COMMAND >${dir}/debug.log 2>&1 & - sleep 2 - logger "已运行debug模式!如需停止,请使用重启/停止服务功能!" 33 - else - $COMMAND >/dev/null 2>&1 & - fi - afstart - ;; + [ -n "$(pidof CrashCore)" ] && $0 stop >/dev/null #禁止多实例 + stop_firewall >/dev/null #清理路由策略 + bfstart + if [ -n "$2" ]; then + if echo "$crashcore" | grep -q 'singbox'; then + sed -i "s/\"level\": \"info\"/\"level\": \"$2\"/" "$TMPDIR"/jsons/log.json 2>/dev/null + else + sed -i "s/log-level: info/log-level: $2/" "$TMPDIR"/config.yaml + fi + [ "$3" = flash ] && dir=$CRASHDIR || dir=$TMPDIR + $COMMAND >${dir}/debug.log 2>&1 & + sleep 2 + logger "已运行debug模式!如需停止,请使用重启/停止服务功能!" 33 + else + $COMMAND >/dev/null 2>&1 & + 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 - sed -i "/alias crash/d" $profile - sed -i "/alias clash/d" $profile - sed -i "/export CRASHDIR/d" $profile - echo "alias crash=\"$CRASHDIR/menu.sh\"" >>$profile - echo "alias clash=\"$CRASHDIR/menu.sh\"" >>$profile - echo "export CRASHDIR=\"$CRASHDIR\"" >>$profile - [ -f "$CRASHDIR"/.dis_startup ] && cronset "保守模式守护进程" || $0 start - ;; + 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 + sed -i "/alias crash/d" $profile + sed -i "/alias clash/d" $profile + sed -i "/export CRASHDIR/d" $profile + echo "alias crash=\"$CRASHDIR/menu.sh\"" >>$profile + echo "alias clash=\"$CRASHDIR/menu.sh\"" >>$profile + echo "export CRASHDIR=\"$CRASHDIR\"" >>$profile + [ -f "$CRASHDIR"/.dis_startup ] && cronset "保守模式守护进程" || $0 start + ;; webget) - #设置临时代理 - if [ -n "$(pidof CrashCore)" ]; then - [ -n "$authentication" ] && auth="$authentication@" - export all_proxy="http://${auth}127.0.0.1:$mix_port" - url=$(echo $3 | sed 's#https://.*jsdelivr.net/gh/juewuy/ShellCrash[@|/]#https://raw.githubusercontent.com/juewuy/ShellCrash/#' | sed 's#https://gh.jwsc.eu.org/#https://raw.githubusercontent.com/juewuy/ShellCrash/#') - else - url=$(echo $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 curl --version >/dev/null 2>&1; then - [ "$4" = "echooff" ] && progress='-s' || progress='-#' - [ "$5" = "rediroff" ] && redirect='' || redirect='-L' - [ "$6" = "skipceroff" ] && certificate='' || certificate='-k' - [ -n "$7" ] && agent="--user-agent \"$7\"" - if curl --version | grep -q '^curl 8.' && ckcmd base64;then - auth_b64=$(echo -n "$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" ] && export all_proxy="" && result=$(curl $agent -w %{http_code} --connect-timeout 5 $progress $redirect $certificate -o "$2" "$3") - else - if wget --version >/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' - [ -n "$7" ] && agent="--user-agent=\"$7\"" - timeout='--timeout=5' - fi - [ "$4" = "echoon" ] && progress='' - [ "$4" = "echooff" ] && progress='-q' - wget -Y on $agent $progress $redirect $certificate $timeout -O "$2" "$url" - if [ "$?" != "0" ]; then - wget -Y off $agent $progress $redirect $certificate $timeout -O "$2" "$3" - [ "$?" = "0" ] && result="200" - else - result="200" - fi - fi - [ "$result" = "200" ] && exit 0 || exit 1 - ;; + #设置临时代理 + if [ -n "$(pidof CrashCore)" ]; then + [ -n "$authentication" ] && auth="$authentication@" + export all_proxy="http://${auth}127.0.0.1:$mix_port" + url=$(echo $3 | sed 's#https://.*jsdelivr.net/gh/juewuy/ShellCrash[@|/]#https://raw.githubusercontent.com/juewuy/ShellCrash/#' | sed 's#https://gh.jwsc.eu.org/#https://raw.githubusercontent.com/juewuy/ShellCrash/#') + else + url=$(echo $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 curl --version >/dev/null 2>&1; then + [ "$4" = "echooff" ] && progress='-s' || progress='-#' + [ "$5" = "rediroff" ] && redirect='' || redirect='-L' + [ "$6" = "skipceroff" ] && certificate='' || certificate='-k' + [ -n "$7" ] && agent="--user-agent \"$7\"" + if curl --version | grep -q '^curl 8.' && ckcmd base64; then + auth_b64=$(echo -n "$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" ] && export all_proxy="" && result=$(curl $agent -w %{http_code} --connect-timeout 5 $progress $redirect $certificate -o "$2" "$3") + else + if wget --version >/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' + [ -n "$7" ] && agent="--user-agent=\"$7\"" + timeout='--timeout=5' + fi + [ "$4" = "echoon" ] && progress='' + [ "$4" = "echooff" ] && progress='-q' + wget -Y on $agent $progress $redirect $certificate $timeout -O "$2" "$url" + if [ "$?" != "0" ]; then + wget -Y off $agent $progress $redirect $certificate $timeout -O "$2" "$3" + [ "$?" = "0" ] && result="200" + else + result="200" + fi + fi + [ "$result" = "200" ] && exit 0 || exit 1 + ;; *) - "$1" "$2" "$3" "$4" "$5" "$6" "$7" - ;; + "$1" "$2" "$3" "$4" "$5" "$6" "$7" + ;; esac diff --git a/scripts/task.sh b/scripts/task.sh index f3e0410c..dbcfdb86 100644 --- a/scripts/task.sh +++ b/scripts/task.sh @@ -21,7 +21,7 @@ ckcmd(){ #检查命令是否存在 #任务命令 check_update(){ #检查更新工具 ${CRASHDIR}/start.sh get_bin ${TMPDIR}/crashversion "$1" echooff - [ "$?" = "0" ] && . ${TMPDIR}/crashversion 2>/dev/null + [ "$?" = "0" ] && . ${TMPDIR}/crashversion 2>/dev/null rm -rf ${TMPDIR}/crashversion } update_core(){ #自动更新内核 @@ -92,7 +92,7 @@ update_scripts(){ #自动更新脚本 if [ -z "$versionsh" -o "$versionsh" = "versionsh_l" ];then logger "任务【自动更新脚本】中止-未检测到版本更新" exit 1 - else + else ${CRASHDIR}/start.sh get_bin ${TMPDIR}/clashfm.tar.gz "bin/update.tar.gz" if [ "$?" != "0" ];then rm -rf ${TMPDIR}/clashfm.tar.gz @@ -112,7 +112,7 @@ update_scripts(){ #自动更新脚本 . ${CRASHDIR}/init.sh >/dev/null ${CRASHDIR}/start.sh start return 0 - fi + fi fi fi } @@ -195,7 +195,7 @@ set_cron(){ [ -z $week ] && week=* [ -z $hour ] && hour=* [ -z $min ] && min=0 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m$cron_time\033[0m执行任务:\033[36m$task_name\033[0m" read -p "是否确认添加定时任务?(1/0) > " res if [ "$res" = '1' ]; then @@ -223,7 +223,7 @@ set_service(){ } #任务界面 task_user_add(){ #自定义命令添加 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m命令可包含空格,请确保命令可执行!\033[0m" echo -e "\033[36m此处不要添加执行条件,请在添加完成后返回添加具体执行条件!\033[0m" echo -e "也可以手动编辑\033[32m${CRASHDIR}/task/task.user\033[0m添加" @@ -238,7 +238,7 @@ task_user_add(){ #自定义命令添加 read -p "请输入任务备注 > " txt [ -n "$txt" ] && task_name=$txt || task_name=自定义任务$task_id echo "$task_id#$task_command#$task_name" >> ${CRASHDIR}/task/task.user - echo -e "\033[32m自定义任务已添加!\033[0m" + echo -e "\033[32m自定义任务已添加!\033[0m" sleep 1 else echo -e "\033[31m输入错误,请重新输入!\033[0m" @@ -246,14 +246,14 @@ task_user_add(){ #自定义命令添加 fi } task_user_del(){ #自定义命令删除 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "请输入对应ID移除对应自定义任务(不会影响内置任务)" echo -e "也可以手动编辑\033[32m${CRASHDIR}/task/task.user\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" cat ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^#' | awk -F '#' '{print $1" "$3}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 0 返回上级菜单 - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num if [ -n "$num" ];then sed -i "/^$num#/d" ${CRASHDIR}/task/task.user 2>/dev/null @@ -264,13 +264,13 @@ task_user_del(){ #自定义命令删除 fi } task_add(){ #任务添加 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请选择需要添加的任务\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" #输出任务列表 cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | awk -F '#' '{print " "NR" "$3}' - echo ----------------------------------------------- - echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num case "$num" in 0) @@ -301,9 +301,9 @@ task_del(){ #任务删除 sed -i "/$1/d" ${CRASHDIR}/task/affirewall 2>/dev/null } task_type(){ #任务条件选择菜单 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "请选择任务\033[36m【$task_name】\033[0m执行条件:" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 定时任务\033[32m每周执行\033[0m" echo -e " 2 定时任务\033[32m每日执行\033[0m" echo -e " 3 定时任务\033[32m每小时执行\033[0m" @@ -312,46 +312,46 @@ task_type(){ #任务条件选择菜单 echo -e " 6 服务\033[33m启动后执行\033[0m" echo -e " 7 服务\033[33m运行时每分钟执行\033[0m" echo -e " 8 防火墙服务\033[33m重启后执行\033[0m" - echo ----------------------------------------------- - echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num case "$num" in - + 0) return 1 ;; 1) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 输入 1-7 对应\033[33m每周的指定某天\033[0m运行(7=周日)" echo -e " 输入 1,4,0 代表\033[36m每周一、周四、周日\033[0m运行" echo -e " 输入 1-5 代表\033[36m周一至周五\033[0m运行" read -p "在每周哪天执行? > " week week=`echo ${week/7/0}` #把7换成0 - echo ----------------------------------------------- - read -p "想在该日的具体哪个小时执行?(0-23) > " hour + echo "-----------------------------------------------" + read -p "想在该日的具体哪个小时执行?(0-23) > " hour cron_time="在每周$week的$hour点整" cron_time=`echo ${cron_time/周0/周日}` #把0换成日 [ -n "$week" ] && [ -n "$hour" ] && set_cron - ;; + ;; 2) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 输入 1,7,15 代表\033[36m每到1,7,15点\033[0m运行" - echo -e " 输入 6-18 代表\033[36m早6点至晚18点间每小时\033[0m运行" - read -p "想在每日的具体哪个小时执行?(0-23) > " hour - echo ----------------------------------------------- + echo -e " 输入 6-18 代表\033[36m早6点至晚18点间每小时\033[0m运行" + read -p "想在每日的具体哪个小时执行?(0-23) > " hour + echo "-----------------------------------------------" read -p "想在具体哪分钟执行?(0-59的整数) > " min cron_time="在每日的$hour点$min分" [ -n "$min" ] && [ -n "$hour" ] && set_cron - ;; + ;; 3) - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "想每隔多少小时执行一次?(1-23的整数) > " num hour="*/$num" cron_time="每隔$num小时" [ -n "$hour" ] && set_cron - ;; + ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "想每隔多少分钟执行一次?(1-59的整数) > " num min="*/$num" cron_time="每隔$num分钟" @@ -364,9 +364,9 @@ task_type(){ #任务条件选择菜单 set_service afstart "$task_id" "服务启动后$task_name" ;; 7) - echo ----------------------------------------------- - echo -e " 输入10即每隔10分钟运行一次,1440即每隔24小时运行一次" - echo -e " 大于60分钟的数值将按小时取整,且按当前时区记时" + echo "-----------------------------------------------" + echo -e " 输入10即每隔10分钟运行一次,1440即每隔24小时运行一次" + echo -e " 大于60分钟的数值将按小时取整,且按当前时区记时" read -p "想每隔多少分钟执行一次?(1-1440的整数) > " num if [ "$num" -lt 60 ];then min="$num" @@ -391,7 +391,7 @@ task_type(){ #任务条件选择菜单 esac } task_manager(){ #任务管理列表 - echo ----------------------------------------------- + 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 @@ -405,28 +405,28 @@ task_manager(){ #任务管理列表 sleep 1 else echo -e "\033[33m已添加的任务:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" cat ${TMPDIR}/task_list | awk '{print " " NR " " $2}' - echo ----------------------------------------------- - echo -e " a 清空旧版任务" + echo "-----------------------------------------------" + echo -e " a 清空旧版任务" echo -e " d 清空任务列表" - echo -e " 0 返回上级菜单" + echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case "$num" in + case "$num" in 0) - ;; + ;; a) task_del "#" echo -e "\033[31m旧版任务已清空!\033[36m" - sleep 1 - ;; + sleep 1 + ;; d) task_del "task.sh" echo -e "\033[31m全部任务已清空!\033[36m" - sleep 1 - ;; + sleep 1 + ;; [1-9]|[1-9][0-9]) - + task_txt=$(sed -n "$num p" ${TMPDIR}/task_list) task_id=$(echo $task_txt | awk '{print $1}') if [ "$task_id" = 0 ];then @@ -440,32 +440,32 @@ 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}') - echo ----------------------------------------------- - echo -e "当前任务为:\033[36m $task_des\033[0m" + echo "-----------------------------------------------" + echo -e "当前任务为:\033[36m $task_des\033[0m" echo -e " 1 \033[33m修改\033[0m当前任务" echo -e " 2 \033[31m删除\033[0m当前任务" - echo -e " 3 \033[32m立即执行\033[0m一次" + echo -e " 3 \033[32m立即执行\033[0m一次" echo -e " 4 查看\033[33m执行记录\033[0m" - echo ----------------------------------------------- - echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" read -p "请选择需要执行的操作 > " num case "$num" in 0) ;; 1) task_type && task_del $task_des - ;; + ;; 2) 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}') eval $task_command && task_res='执行成功!' || task_res='执行失败!' logger "任务【$task_des】$task_res" 33 off sleep 1 - ;; + ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep "$task_name")" ];then cat ${TMPDIR}/ShellCrash.log | grep "$task_name" else @@ -476,7 +476,7 @@ task_manager(){ #任务管理列表 *) errornum ;; - esac + esac fi task_manager ;; @@ -487,17 +487,17 @@ task_manager(){ #任务管理列表 fi } task_recom(){ #任务推荐 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m启用推荐的自动任务配置?这包括:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "每隔10分钟自动保存面板配置" echo -e "服务启动后自动同步ntp时间" echo -e "在每日的3点0分重启服务" - echo ----------------------------------------------- - read -p "是否启用?(1/0) > " res + echo "-----------------------------------------------" + read -p "是否启用?(1/0) > " res [ "$res" = 1 ] && { set_service running "106" "运行时每10分钟自动保存面板配置" "*/10 * * * *" - set_service afstart "107" "服务启动后自动同步ntp时间" + set_service afstart "107" "服务启动后自动同步ntp时间" cronset "在每日的3点0分重启服务" "0 3 * * * ${CRASHDIR}/task/task.sh 103 在每日的3点0分重启服务" && \ echo -e "任务【在每日的3点0分重启服务】\033[32m添加成功!\033[0m" } @@ -505,9 +505,9 @@ task_recom(){ #任务推荐 task_menu(){ #任务菜单 #检测并创建自定义任务文件 [ -f ${CRASHDIR}/task/task.user ] || echo '#任务ID(必须>200并顺序排列)#任务命令#任务说明(#号隔开,任务命令和说明中都不允许包含#号)' > ${CRASHDIR}/task/task.user - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m欢迎使用自动任务功能:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 添加\033[32m自动任务\033[0m" echo -e " 2 管理\033[33m任务列表\033[0m" echo -e " 3 查看\033[36m任务日志\033[0m" @@ -515,8 +515,8 @@ task_menu(){ #任务菜单 echo -e " 5 添加\033[33m自定义任务\033[0m" echo -e " 6 删除\033[33m自定义任务\033[0m" echo -e " 7 使用\033[32m推荐设置\033[0m" - echo ----------------------------------------------- - echo -e " 0 返回上级菜单" + echo "-----------------------------------------------" + echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num case "$num" in 0) @@ -524,15 +524,15 @@ task_menu(){ #任务菜单 1) task_add task_menu - ;; + ;; 2) task_manager rm -rf ${TMPDIR}/task_list task_menu - ;; + ;; 3) if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep '任务【')" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" cat ${TMPDIR}/ShellCrash.log | grep '任务【' else echo -e "\033[31m未找到任务相关执行日志!\033[0m" @@ -541,7 +541,7 @@ task_menu(){ #任务菜单 task_menu ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请在日志工具中配置相关推送通道及推送开关\033[0m" log_pusher task_menu @@ -561,9 +561,9 @@ task_menu(){ #任务菜单 *) errornum ;; - + esac - + } case "$1" in @@ -581,4 +581,3 @@ case "$1" in $1 ;; esac - diff --git a/scripts/webget.sh b/scripts/webget.sh index e6c2a015..8f8f3c9b 100644 --- a/scripts/webget.sh +++ b/scripts/webget.sh @@ -14,19 +14,19 @@ dir_avail(){ #导入订阅、配置文件相关 setrules(){ #自定义规则 set_rule_type(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请选择规则类型\033[0m" echo $rule_type | awk -F ' ' '{for(i=1;i<=NF;i++){print i" "$i}}' echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; [0-9]*) if [ $num -gt $(echo $rule_type | awk -F " " '{print NF}') ];then errornum else rule_type_set=$(echo $rule_type|cut -d' ' -f$num) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请输入规则语句,可以是域名、泛域名、IP网段或者其他匹配规则类型的内容\033[0m" read -p "请输入对应规则 > " rule_state_set [ -n "$rule_state_set" ] && set_group_type || errornum @@ -38,13 +38,13 @@ setrules(){ #自定义规则 esac } set_group_type(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请选择具体规则\033[0m" echo -e "\033[33m此处规则读取自现有配置文件,如果你后续更换配置文件时运行出错,请尝试重新添加\033[0m" echo $rule_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; [0-9]*) if [ $num -gt $(echo $rule_group | awk -F "#" '{print NF}') ];then @@ -54,7 +54,7 @@ setrules(){ #自定义规则 rule_all="- ${rule_type_set},${rule_state_set},${rule_group_set}" [ -n "$(echo IP-CIDR SRC-IP-CIDR IP-CIDR6|grep "$rule_type_set")" ] && rule_all="${rule_all},no-resolve" echo $rule_all >> $YAMLSDIR/rules.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m添加成功!\033[0m" fi ;; @@ -67,10 +67,10 @@ setrules(){ #自定义规则 echo -e "输入对应数字即可移除相应规则:" sed -i '/^ *$/d; /^#/d' $YAMLSDIR/rules.yaml cat $YAMLSDIR/rules.yaml | grep -Ev '^#' | awk -F "#" '{print " "NR" "$1$2$3}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; '') ;; *) @@ -87,19 +87,19 @@ setrules(){ #自定义规则 get_rule_group(){ "$CRASHDIR"/start.sh get_save http://127.0.0.1:${db_port}/proxies | sed 's/:{/!/g' | awk -F '!' '{for(i=1;i<=NF;i++) print $i}' | grep -aE '"Selector|URLTest|LoadBalance"' | grep -aoE '"name":.*"now":".*",' | awk -F '"' '{print "#"$4}' | tr -d '\n' } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m你可以在这里快捷管理自定义规则\033[0m" echo -e "如需批量操作,请手动编辑:\033[36m $YAMLSDIR/rules.yaml\033[0m" echo -e "\033[33msingbox和clash共用此处规则,可无缝切换!\033[0m" echo -e "大量规则请尽量使用rule-set功能添加,\033[31m此处过量添加可能导致启动卡顿!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 新增自定义规则" echo -e " 2 移除自定义规则" echo -e " 3 清空规则列表" echo "$crashcore" | grep -q 'singbox' || echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; 1) @@ -109,7 +109,7 @@ setrules(){ #自定义规则 setrules ;; 2) - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ -s $YAMLSDIR/rules.yaml ];then del_rule_type else @@ -124,7 +124,7 @@ setrules(){ #自定义规则 setrules ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ "$proxies_bypass" = "未启用" ];then echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" @@ -144,12 +144,12 @@ setrules(){ #自定义规则 } setgroups(){ #自定义clash策略组 set_group_type(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m注意策略组名称必须和【自定义规则】或【自定义节点】功能中指定的策略组一致!\033[0m" echo -e "\033[33m建议先创建策略组,之后可在【自定义规则】或【自定义节点】功能中智能指定\033[0m" echo -e "\033[33m如需在当前策略组下添加节点,请手动编辑$YAMLSDIR/proxy-groups.yaml\033[0m" read -p "请输入自定义策略组名称(不支持纯数字且不要包含特殊字符!) > " new_group_name - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m请选择策略组【$new_group_name】的类型!\033[0m" echo $group_type_cn | awk '{for(i=1;i<=NF;i++){print i" "$i}}' read -p "请输入对应数字 > " num @@ -173,20 +173,20 @@ setgroups(){ #自定义clash策略组 - DIRECT EOF sed -i "/^ *$/d" $YAMLSDIR/proxy-groups.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m添加成功!\033[0m" } set_group_add(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请选择想要将本策略添加到的策略组\033[0m" echo -e "\033[32m如需添加到多个策略组,请一次性输入多个数字并用空格隔开\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo $proxy_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 跳过添加" read -p "请输入对应数字(多个用空格隔开) > " char - case $char in + case "$char" in 0) ;; *) for num in $char;do @@ -202,16 +202,16 @@ EOF ;; esac } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m你可以在这里快捷管理自定义策略组\033[0m" echo -e "\033[36m如需修改或批量操作,请手动编辑:$YAMLSDIR/proxy-groups.yaml\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 添加自定义策略组" echo -e " 2 查看自定义策略组" echo -e " 3 清空自定义策略组" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; 1) @@ -222,7 +222,7 @@ EOF setgroups ;; 2) - echo ----------------------------------------------- + echo "-----------------------------------------------" cat $YAMLSDIR/proxy-groups.yaml setgroups ;; @@ -238,7 +238,7 @@ EOF } setproxies(){ #自定义clash节点 set_proxy_type(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m注意节点格式必须是单行,不包括括号,name:必须写在最前,例如:\033[0m" echo -e "\033[36m【name: \"test\", server: 192.168.1.1, port: 12345, type: socks5, udp: true】\033[0m" echo -e "更多写法请参考:\033[32m https://juewuy.github.io/ \033[0m" @@ -252,16 +252,16 @@ setproxies(){ #自定义clash节点 fi } set_group_add(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请选择想要将节点添加到的策略组\033[0m" echo -e "\033[32m如需添加到多个策略组,请一次性输入多个数字并用空格隔开\033[0m" echo -e "\033[33m如需自定义策略组,请先使用【管理自定义策略组功能】添加\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo $proxy_group | awk -F '#' '{for(i=1;i<=NF;i++){print i" "$i}}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 返回上级菜单" read -p "请输入对应数字(多个用空格隔开) > " char - case $char in + case "$char" in 0) ;; *) for num in $char;do @@ -270,7 +270,7 @@ setproxies(){ #自定义clash节点 done if [ -n "$rule_group_add" ];then echo "- {$proxy_state_set}$rule_group_add" >> $YAMLSDIR/proxies.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m添加成功!\033[0m" unset rule_group_add else @@ -279,17 +279,17 @@ setproxies(){ #自定义clash节点 ;; esac } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m你可以在这里快捷管理自定义节点\033[0m" echo -e "\033[36m如需批量操作,请手动编辑:$YAMLSDIR/proxies.yaml\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 添加自定义节点" echo -e " 2 管理自定义节点" echo -e " 3 清空自定义节点" echo -e " 4 配置节点绕过: \033[36m$proxies_bypass\033[0m" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num - case $num in + case "$num" in 0) ;; 1) @@ -299,12 +299,12 @@ setproxies(){ #自定义clash节点 setproxies ;; 2) - echo ----------------------------------------------- + echo "-----------------------------------------------" sed -i '/^ *$/d' $YAMLSDIR/proxies.yaml 2>/dev/null if [ -s $YAMLSDIR/proxies.yaml ];then echo -e "当前已添加的自定义节点为:" cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | awk -F '[,,}]' '{print NR, $1, $NF}' | sed 's/- {//g' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m输入节点对应数字可以移除对应节点\033[0m" read -p "请输入对应数字 > " num if [ $num -le $(cat $YAMLSDIR/proxies.yaml | grep -Ev '^#' | wc -l) ];then @@ -324,7 +324,7 @@ setproxies(){ #自定义clash节点 setproxies ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ "$proxies_bypass" = "未启用" ];then echo -e "\033[33m本功能会自动将当前配置文件中的节点域名或IP设置为直连规则以防止出现双重流量!\033[0m" echo -e "\033[33m请确保下游设备使用的节点与ShellCrash中使用的节点相同,否则无法生效!\033[0m" @@ -379,7 +379,7 @@ EOF else provider_temp_file=$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg | awk -F '=' '{print $2}') fi - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ -s ${provider_temp_file} ];then ln -sf ${provider_temp_file} ${TMPDIR}/provider_temp_file else @@ -476,7 +476,7 @@ EOF else provider_temp_file=$(grep "provider_temp_${coretype}" ${CRASHDIR}/configs/ShellCrash.cfg | awk -F '=' '{print $2}') fi - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ -s ${provider_temp_file} ];then ln -sf ${provider_temp_file} ${TMPDIR}/provider_temp_file else @@ -547,25 +547,25 @@ setproviders(){ #自定义providers provider_temp_des=$(grep "$provider_temp_file" ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print $1}') [ -z "$provider_temp_des" ] && provider_temp_des=$provider_temp_file fi - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m你可以在这里快捷管理与生成自定义的providers服务商\033[0m" echo -e "\033[33m支持在线及本地的Yaml格式配置导入\033[0m" [ -s $CRASHDIR/configs/providers.cfg ] && { - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m输入对应数字可管理providers服务商\033[0m" cat $CRASHDIR/configs/providers.cfg | awk -F "#" '{print " "NR" "$1" "$2}' } echo -e " d \033[31m清空\033[0mproviders服务商列表" echo -e " e \033[33m清理\033[0mproviders目录文件" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m按照a-b-c的顺序即可完成配置生成\033[0m" echo -e " a \033[36m添加\033[0mproviders服务商/节点" echo -e " b 选择\033[33m规则模版\033[0m \033[32m$provider_temp_des\033[0m" echo -e " c \033[32m生成\033[0m基于providers的配置文件" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 返回上级菜单" read -p "请输入对应字母或数字 > " num - case $num in + case "$num" in 0) ;; [1-9]|[1-9][0-9]) @@ -574,12 +574,12 @@ setproviders(){ #自定义providers if [ -z "$provider_name" ];then errornum else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 修改名称:\033[36m$provider_name\033[0m" echo -e " 2 修改链接地址:\033[32m$provider_url\033[0m" echo -e " 3 生成\033[33m仅包含此链接\033[0m的配置文件" echo -e " 4 \033[31m移除此链接\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 返回上级菜单" read -p "请选择需要执行的操作 > " num case "$num" in @@ -617,17 +617,17 @@ setproviders(){ #自定义providers setproviders ;; a) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "支持填写在线的\033[32mYClash订阅地址\033[0m或者\033[32m本地Clash配置文件\033[0m" echo -e "本地配置文件请放在\033[32m$CRASHDIR\033[0m目录下,并填写相对路径如【\033[32m./providers/test.yaml\033[0m】" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入链接地址或本地相对路径 > " link link=$(echo $link | sed 's/ //g') #去空格 [ -n "$(echo $link | grep -E '.*\..*|^\./')" ] && { read -p "请输入名称或代号(不可重复,不支持纯数字) > " name name=$(echo $name | sed 's/ //g') [ -n "$name" ] && [ -z "$(echo "$name" | grep -E '^[0-9]+$')" ] && ! grep -q "$name" $CRASHDIR/configs/providers.cfg && { - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "名称:\033[36m$name\033[0m" echo -e "链接地址/路径:\033[32m$link\033[0m" read -p "确认添加?(1/0) > " res @@ -642,10 +642,10 @@ setproviders(){ #自定义providers setproviders ;; c) - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ -s $CRASHDIR/configs/providers.cfg ];then echo -e "\033[33msingboxr与mihomo内核的providers配置文件不互通!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "确认生成${coretype}配置文件?(1/0) > " res [ "$res" = "1" ] && { gen_${coretype}_providers @@ -657,16 +657,16 @@ setproviders(){ #自定义providers setproviders ;; b) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "当前规则模版为:\033[32m$provider_temp_des\033[0m" echo -e "\033[33m请选择在线模版:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" cat ${CRASHDIR}/configs/${coretype}_providers.list | awk '{print " "NR" "$1}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " a 使用\033[36m本地模版\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应字母或数字 > " num - case $num in + case "$num" in 0) ;; a) @@ -726,33 +726,33 @@ EOF #script: #listeners: EOF - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m已经创建自定义设定文件:$YAMLSDIR/user.yaml !\033[0m" echo -e "\033[33m可用于编写自定义的DNS,等功能\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m已经创建自定义功能文件:$YAMLSDIR/others.yaml !\033[0m" echo -e "\033[33m可用于编写自定义的锚点、入站、proxy-providers、sub-rules、rule-set、script等功能\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "Windows下请\n使用\033[33mWinSCP软件\033[0m进行编辑!\033[0m" echo -e "MacOS下请\n使用\033[33mSecureFX软件\033[0m进行编辑!\033[0m" echo -e "Linux本机可\n使用\033[33mvim\033[0m进行编辑(路由设备可能不显示中文请勿使用)!\033[0m" } set_singbox_adv(){ #自定义singbox配置文件 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "支持覆盖脚本设置的模块有:\033[0m" echo -e "\033[36mlog dns ntp certificate experimental\033[0m" echo -e "支持与内置功能合并(但不可冲突)的模块有:\033[0m" echo -e "\033[36mendpoints inbounds outbounds providers route services\033[0m" echo -e "将相应json文件放入\033[33m$JSONSDIR\033[0m目录后即可在启动时自动加载" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "使用前请务必参考配置教程:\033[32;4m https://juewuy.github.io/nWTjEpkSK \033[0m" } override(){ #配置文件覆写 [ -z "$rule_link" ] && rule_link=1 [ -z "$server_link" ] && server_link=1 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m 欢迎使用配置文件覆写功能!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 自定义\033[32m端口及秘钥\033[0m" echo -e " 2 管理\033[36m自定义规则\033[0m" echo "$crashcore" | grep -q 'singbox' || { @@ -761,7 +761,7 @@ override(){ #配置文件覆写 } echo -e " 5 \033[32m自定义\033[0m高级功能" [ "$disoverride" != 1 ] && echo -e " 9 \033[33m禁用\033[0m配置文件覆写" - echo ----------------------------------------------- + echo "-----------------------------------------------" [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num case "$num" in @@ -769,7 +769,7 @@ override(){ #配置文件覆写 ;; 1) if [ -n "$(pidof CrashCore)" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m检测到服务正在运行,需要先停止服务!\033[0m" read -p "是否停止服务?(1/0) > " res if [ "$res" = "1" ];then @@ -799,17 +799,17 @@ override(){ #配置文件覆写 override ;; 9) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m此功能可能会导致严重问题!启用后脚本中大部分功能都将禁用!!!\033[0m" echo -e "如果你不是非常了解$crashcore的运行机制,切勿开启!\033[0m" echo -e "\033[33m继续后如出现任何问题,请务必自行解决,一切提问恕不受理!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" sleep 2 read -p "我确认遇到问题可以自行解决[1/0] > " res [ "$res" = '1' ] && { disoverride=1 setconfig disoverride $disoverride - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m设置成功!\033[0m" } override @@ -821,10 +821,10 @@ override(){ #配置文件覆写 } gen_link_config(){ #选择在线规则 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 当前使用规则为:$(grep -aE '^5' ${CRASHDIR}/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $2}') grep -aE '^5' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$2$4}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 0 返回上级菜单 read -p "请输入对应数字 > " num totalnum=$(grep -acE '^5' ${CRASHDIR}/configs/servers.list ) @@ -836,17 +836,17 @@ gen_link_config(){ #选择在线规则 #将对应标记值写入配置 rule_link=$num setconfig rule_link $rule_link - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m设置成功!返回上级菜单\033[0m" fi } gen_link_server(){ #选择在线服务器 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m以下为互联网采集的第三方服务器,具体安全性请自行斟酌!\033[0m" echo -e "\033[32m感谢以下作者的无私奉献!!!\033[0m" echo 当前使用后端为:$(grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}') grep -aE '^3|^4' ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$3" "$2}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 0 返回上级菜单 read -p "请输入对应数字 > " num totalnum=$(grep -acE '^3|^4' ${CRASHDIR}/configs/servers.list ) @@ -858,25 +858,25 @@ gen_link_server(){ #选择在线服务器 #将对应标记值写入配置 server_link=$num setconfig server_link $server_link - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m设置成功!返回上级菜单\033[0m" fi } gen_link_flt(){ #在线生成节点过滤 [ -z "$exclude" ] && exclude="未设置" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m当前过滤关键字:\033[47;30m$exclude\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m匹配关键字的节点会在导入时被【屏蔽】!!!\033[0m" echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 000 \033[31m删除\033[0m关键字" echo -e " 回车 取消输入并返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入关键字 > " exclude if [ "$exclude" = '000' ]; then - echo ----------------------------------------------- + echo "-----------------------------------------------" exclude='' echo -e "\033[31m 已删除节点过滤关键字!!!\033[0m" fi @@ -884,19 +884,19 @@ gen_link_flt(){ #在线生成节点过滤 } gen_link_ele(){ #在线生成节点筛选 [ -z "$include" ] && include="未设置" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m当前筛选关键字:\033[47;30m$include\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m仅有匹配关键字的节点才会被【导入】!!!\033[0m" echo -e "多个关键字可以用\033[30;47m | \033[0m号分隔" echo -e "\033[32m支持正则表达式\033[0m,空格请使用\033[30;47m + \033[0m号替代" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 000 \033[31m删除\033[0m关键字" echo -e " 回车 取消输入并返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入关键字 > " include if [ "$include" = '000' ]; then - echo ----------------------------------------------- + echo "-----------------------------------------------" include='' echo -e "\033[31m 已删除节点匹配关键字!!!\033[0m" fi @@ -913,26 +913,26 @@ get_core_config(){ #调用工具下载 fi } gen_core_config_link(){ #在线生成工具 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m 欢迎使用在线生成配置文件功能!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" #设置输入循环 i=1 while [ $i -le 99 ] do - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m本功能依赖第三方在线subconverter服务实现,脚本本身不提供任何代理服务!\033[0m" echo -e "\033[31m严禁使用本脚本从事任何非法活动,否则一切后果请自负!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "支持批量(<=99)导入订阅链接、分享链接" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 \033[36m开始生成配置文件\033[0m(原文件将被备份)" echo -e " 2 设置\033[31m节点过滤\033[0m关键字 \033[47;30m$exclude\033[0m" echo -e " 3 设置\033[32m节点筛选\033[0m关键字 \033[47;30m$include\033[0m" echo -e " 4 选取在线\033[33m配置规则模版\033[0m" echo -e " 5 \033[0m选取在线生成服务器\033[0m" echo -e " 0 \033[31m撤销输入并返回上级菜单\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请直接输入第${i}个链接或对应数字选项 > " link link=$(echo $link | sed 's/\&/%26/g') #处理分隔符 test=$(echo $link | grep "://") @@ -958,7 +958,7 @@ gen_core_config_link(){ #在线生成工具 #获取在线yaml文件 get_core_config else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m请先输入订阅或分享链接!\033[0m" sleep 1 fi @@ -980,28 +980,28 @@ gen_core_config_link(){ #在线生成工具 i=100 else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m请输入正确的链接或者数字!\033[0m" sleep 1 fi done } set_core_config_link(){ #直接导入配置 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m仅限导入完整的配置文件链接!!!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "注意:\033[31m此功能不兼容“跳过证书验证”功能,部分老旧\n设备可能出现x509报错导致节点不通\033[0m" echo -e "你也可以搭配在线订阅转换网站或者自建SubStore使用" echo "$crashcore" | grep -q 'singbox' &&echo -e "singbox内核建议使用\033[32;4mhttps://subv.jwsc.eu.org/\033[0m转换" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m0 返回上级菜单\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入完整链接 > " link test=$(echo $link | grep -iE "tp.*://" ) link=`echo ${link/\ \(*\)/''}` #删除恶心的超链接内容 link=`echo ${link//\&/\\\&}` #处理分隔符 if [ -n "$link" -a -n "$test" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e 请检查输入的链接是否正确: echo -e "\033[4;32m$link\033[0m" read -p "确认导入配置文件?原配置文件将被备份![1/0] > " res @@ -1018,7 +1018,7 @@ set_core_config_link(){ #直接导入配置 elif [ "$link" = 0 ];then i= else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m请输入正确的配置文件链接地址!!!\033[0m" echo -e "\033[33m仅支持http、https、ftp以及ftps链接!\033[0m" sleep 1 @@ -1029,9 +1029,9 @@ set_core_config(){ #配置文件功能 [ -z "$rule_link" ] && rule_link=1 [ -z "$server_link" ] && server_link=1 echo "$crashcore" | grep -q 'singbox' && config_path=${JSONSDIR}/config.json || config_path=${YAMLSDIR}/config.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m ShellCrash配置文件管理\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 在线\033[32m生成配置文件\033[0m(基于Subconverter订阅转换)" if [ -f "$CRASHDIR"/v2b_api.sh ];then echo -e " 2 登录\033[33m获取订阅(推荐!)\033[0m" @@ -1045,7 +1045,7 @@ set_core_config(){ #配置文件功能 echo -e " 7 \033[33m更新\033[0m配置文件" echo -e " 8 \033[36m还原\033[0m配置文件" echo -e " 9 自定义浏览器UA \033[32m$user_agent\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" [ "$inuserguide" = 1 ] || echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num case "$num" in @@ -1053,14 +1053,14 @@ set_core_config(){ #配置文件功能 ;; 1) if [ -n "$Url" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m检测到已记录的链接内容:\033[0m" echo -e "\033[4;32m$Url\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "清空链接/追加导入?[1/0] > " res if [ "$res" = '1' ]; then Url_link="" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m链接已清空!\033[0m" else Url_link=$Url @@ -1093,7 +1093,7 @@ set_core_config(){ #配置文件功能 set_core_config ;; 4) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请将本地配置文件上传到/tmp目录并重命名为config.yaml或者config.json\033[0m" echo -e "\033[32m之后重新运行本脚本即可自动弹出导入提示!\033[0m" exit @@ -1113,15 +1113,15 @@ set_core_config(){ #配置文件功能 ;; 7) if [ -z "$Url" -a -z "$Https" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m没有找到你的配置文件/订阅链接!请先输入链接!\033[0m" sleep 1 set_core_config else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m当前系统记录的链接为:\033[0m" echo -e "\033[4;32m$Url$Https\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "确认更新配置文件?[1/0] > " res if [ "$res" = '1' ]; then get_core_config @@ -1132,32 +1132,32 @@ set_core_config(){ #配置文件功能 ;; 8) if [ ! -f ${config_path}.bak ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m没有找到配置文件的备份!\033[0m" set_core_config else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e 备份文件共有"\033[32m`wc -l < ${config_path}.bak`\033[0m"行内容,当前文件共有"\033[32m`wc -l < ${config_path}`\033[0m"行内容 read -p "确认还原配置文件?此操作不可逆![1/0] > " res if [ "$res" = '1' ]; then mv ${config_path}.bak ${config_path} - echo ----------------------------------------------- + echo "----------------------------------------------" echo -e "\033[32m配置文件已还原!请手动重启服务!\033[0m" sleep 1 else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m操作已取消!返回上级菜单!\033[0m" set_core_config fi fi ;; 9) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m如果6-1或者6-2无法正确获取配置文件时可以尝试使用\033[0m" - echo -e " 1 使用自动UA" + echo -e " 1 使用自动UA" echo -e " 2 不使用UA" echo -e " 3 使用自定义UA:\033[32m$user_agent\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in 0) @@ -1178,7 +1178,7 @@ set_core_config(){ #配置文件功能 ;; esac [ "$num" -le 3 ] && setconfig user_agent "$user_agent" - set_core_config + set_core_config ;; *) errornum @@ -1194,8 +1194,8 @@ getscripts(){ #更新脚本文件 else ${CRASHDIR}/start.sh stop 2>/dev/null #解压 - echo ----------------------------------------------- - echo 开始解压文件! + echo "-----------------------------------------------" + echo "开始解压文件!" mkdir -p ${CRASHDIR} > /dev/null tar -zxf "${TMPDIR}/ShellCrash.tar.gz" ${tar_para} -C ${CRASHDIR}/ if [ $? -ne 0 ];then @@ -1210,19 +1210,19 @@ getscripts(){ #更新脚本文件 exit } setscripts(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "当前脚本版本为:\033[33m $versionsh_l \033[0m" echo -e "最新脚本版本为:\033[32m $version_new \033[0m" echo -e "注意更新时会停止服务!" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "是否更新脚本?[1/0] > " res if [ "$res" = '1' ]; then #下载更新 getscripts #提示 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m管理脚本更新成功!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" exit; fi } @@ -1242,12 +1242,12 @@ getcpucore(){ #自动获取内核架构 } setcpucore(){ #手动设置内核架构 cpucore_list="armv5 armv7 arm64 386 amd64 mipsle-softfloat mipsle-hardfloat mips-softfloat" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m仅适合脚本无法正确识别核心或核心无法正常运行时使用!\033[0m" echo -e "当前可供在线下载的处理器架构为:" echo $cpucore_list | awk -F " " '{for(i=1;i<=NF;i++) {print i" "$i }}' echo -e "不知道如何获取核心版本?请参考:\033[36;4mhttps://juewuy.github.io/bdaz\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num [ -n "$num" ] && setcpucore=$(echo $cpucore_list | awk '{print $"'"$num"'"}' ) if [ -z "$setcpucore" ];then @@ -1314,8 +1314,8 @@ getcore(){ #下载内核文件 [ -z "$cpucore" ] && getcpucore echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash #获取在线内核文件 - echo ----------------------------------------------- - echo 正在在线获取$crashcore核心文件…… + 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$') @@ -1387,15 +1387,15 @@ setcustcore(){ #自定义内核 rm -rf ${TMPDIR}/github_api # if [ -s ${TMPDIR}/core.list ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "内核版本:\033[36m$release_tag\033[0m" echo -e "发布时间:\033[33m$release_date\033[0m" echo -e "更新时间:\033[32m$update_date\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请确认内核信息并选择:\033[0m" cat ${TMPDIR}/core.list | grep -oE "$release_tag.*" | sed 's|.*/||' | awk '{print " "NR" "$1}' echo -e " 0 返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in 0) @@ -1424,16 +1424,16 @@ setcustcore(){ #自定义内核 rm -rf ${TMPDIR}/core.list } [ -z "$cpucore" ] && getcpucore - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m此处内核通常源自互联网采集,此处致谢各位开发者!\033[0m" echo -e "\033[33m自定义内核未经过完整适配,使用出现问题请自行解决!\033[0m" echo -e "\033[31m自定义内核已适配定时任务,但不支持小闪存模式!\033[0m" echo -e "\033[32m如遇到网络错误请先启动ShellCrash服务!\033[0m" [ -n "$custcore" ] && { - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "当前内核为:\033[36m$custcore\033[0m" } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请选择需要使用的核心!\033[0m" echo -e "1 \033[36mMetaCubeX/mihomo\033[32m@release\033[0m版本官方内核" echo -e "2 \033[36mMetaCubeX/mihomo\033[32m@alpha\033[0m版本官方内核" @@ -1443,7 +1443,7 @@ setcustcore(){ #自定义内核 echo -e "6 \033[36mreF1nd/sing-box\033[32m@dev\033[0m版本内核(完整编译)" echo -e "7 Premium-2023.08.17内核(已停止维护)" echo -e "a \033[33m自定义内核链接 \033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in 1) @@ -1506,13 +1506,13 @@ setcore(){ #内核选择菜单 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 ----------------------------------------------- + echo "-----------------------------------------------" [ -z "$cpucore" ] && getcpucore echo -e "当前内核:\033[42;30m $crashcore \033[47;30m$core_v\033[0m" echo -e "当前系统处理器架构:\033[32m $cpucore \033[0m" echo -e "\033[33m请选择需要使用的核心版本!\033[0m" echo -e "\033[36m如需本地上传,请将二进制文件上传至 /tmp 目录后重新运行crash命令\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "1 \033[43;30m Mihomo \033[0m: \033[32m(原meta内核)支持全面\033[0m" echo -e " >>\033[32m$meta_v \033[33m占用略高\033[0m" echo -e " 说明文档: \033[36;4mhttps://wiki.metacubex.one\033[0m" @@ -1525,12 +1525,12 @@ setcore(){ #内核选择菜单 echo -e "4 \033[43;30m Clash \033[0m: \033[32m占用低\033[0m" echo -e " >>\033[32m$clash_v \033[33m不安全,已停止维护\033[0m" echo -e " 说明文档: \033[36;4mhttps://lancellc.gitbook.io\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "5 \033[36m自定义内核\033[0m $custcore" echo -e "6 \033[32m更新当前内核\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo "9 手动指定处理器架构" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 0 返回上级菜单 read -p "请输入对应数字 > " num case "$num" in @@ -1578,11 +1578,11 @@ setcore(){ #内核选择菜单 getgeo(){ #下载Geo文件 #生成链接 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 正在从服务器获取数据库文件………… ${CRASHDIR}/start.sh get_bin ${TMPDIR}/${geoname} bin/geodata/$geotype if [ "$?" = "1" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" error_down else @@ -1597,7 +1597,7 @@ getgeo(){ #下载Geo文件 else mv -f ${TMPDIR}/${geoname} ${BINDIR}/${geofile}${geoname} fi - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" geo_v="$(echo $geotype | awk -F "." '{print $1}')_v" setconfig $geo_v $GeoIP_v @@ -1606,11 +1606,11 @@ getgeo(){ #下载Geo文件 } setcustgeo(){ #下载自定义数据库文件 getcustgeo(){ - echo ----------------------------------------------- - echo 正在获取数据库文件………… + echo "-----------------------------------------------" + echo "正在获取数据库文件…………" ${CRASHDIR}/start.sh webget ${TMPDIR}/$geoname $custgeolink if [ "$?" = "1" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" error_down else @@ -1619,7 +1619,7 @@ setcustgeo(){ #下载自定义数据库文件 [ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset } mv -f ${TMPDIR}/${geoname} ${BINDIR}/${geofile}${geoname} - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m$geotype数据库文件下载成功!\033[0m" fi sleep 1 @@ -1635,10 +1635,10 @@ setcustgeo(){ #下载自定义数据库文件 } if [ -s ${TMPDIR}/geo.list ];then echo -e "请选择需要更新的数据库文件:" - echo ----------------------------------------------- + echo "-----------------------------------------------" cat ${TMPDIR}/geo.list | awk '{print " "NR" "$1}' echo -e " 0 返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in 0) @@ -1666,19 +1666,19 @@ setcustgeo(){ #下载自定义数据库文件 fi } rm -rf ${TMPDIR}/geo.list - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m此处数据库均源自互联网采集,此处致谢各位开发者!\033[0m" echo -e "\033[32m请点击或复制链接前往项目页面查看具体说明!\033[0m" echo -e "\033[31m自定义数据库不支持定时任务及小闪存模式!\033[0m" echo -e "\033[33m如遇到网络错误请先启动ShellCrash服务!\033[0m" echo -e "\033[0m请选择需要更新的数据库项目来源:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 \033[36;4mhttps://github.com/MetaCubeX/meta-rules-dat\033[0m (仅限Clash/Mihomo)" echo -e " 2 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Clash/Mihomo)" echo -e " 3 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限SingBox-srs)" echo -e " 4 \033[36;4mhttps://github.com/DustinWin/ruleset_geodata\033[0m (仅限Mihomo-mrs)" echo -e " 5 \033[36;4mhttps://github.com/Loyalsoldier/geoip\033[0m (仅限Clash-GeoIP)" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 9 \033[33m自定义数据库链接 \033[0m" echo -e " 0 返回上级菜单" read -p "请输入对应数字 > " num @@ -1729,24 +1729,24 @@ setcustgeo(){ #下载自定义数据库文件 setgeo(){ #数据库选择菜单 . $CFG_PATH > /dev/null [ -n "$cn_mini_v" ] && geo_type_des=精简版 || geo_type_des=全球版 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m请选择需要更新的Geo数据库文件:\033[0m" echo -e "\033[36mMihomo内核和SingBox内核的数据库文件不通用\033[0m" echo -e "在线数据库最新版本(每日同步上游):\033[32m$GeoIP_v\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 CN-IP绕过文件(约0.1mb) \033[33m$china_ip_list_v\033[0m" echo -e " 2 CN-IPV6绕过文件(约30kb) \033[33m$china_ipv6_list_v\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 3 Mihomo精简版GeoIP_cn数据库(约0.1mb) \033[33m$cn_mini_v\033[0m" echo -e " 4 Mihomo完整版GeoSite数据库(约5mb) \033[33m$geosite_v\033[0m" echo -e " 5 Mihomo-mrs数据库常用包(约1mb) \033[33m$mrs_v\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 6 Singbox-srs数据库常用包(约0.8mb) \033[33m$srs_v\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 8 \033[32m自定义数据库文件\033[0m" echo -e " 9 \033[31m清理数据库文件\033[0m" echo " 0 返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num case "$num" in 0) @@ -1792,10 +1792,10 @@ setgeo(){ #数据库选择菜单 setgeo ;; 9) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m这将清理$CRASHDIR目录及/ruleset目录下所有数据库文件!\033[0m" echo -e "\033[36m清理后启动服务即可自动下载所需文件~\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "确认清理?[1/0] > " res [ "$res" = '1' ] && { for file in cn_ip.txt cn_ipv6.txt Country.mmdb GeoSite.dat geoip.db geosite.db;do @@ -1818,13 +1818,13 @@ esac getdb(){ #下载Dashboard文件 dblink="${update_url}/" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo 正在连接服务器获取安装文件………… ${CRASHDIR}/start.sh get_bin ${TMPDIR}/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz if [ "$?" = "1" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" error_down setdb else @@ -1843,7 +1843,7 @@ getdb(){ #下载Dashboard文件 fi #写入配置文件 setconfig hostdir "'$hostdir'" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m面板安装成功!\033[36m如未生效,请使用【Ctrl+F5】强制刷新浏览器!!!\033[0m" rm -rf ${TMPDIR}/clashdb.tar.gz fi @@ -1852,9 +1852,9 @@ getdb(){ #下载Dashboard文件 setdb(){ dbdir(){ if [ -f /www/clash/CNAME -o -f ${CRASHDIR}/ui/CNAME ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m检测到您已经安装过本地面板了!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "是否升级/覆盖安装?[1/0] > " res if [ "$res" = 1 ]; then rm -rf ${BINDIR}/ui @@ -1866,12 +1866,12 @@ setdb(){ echo -e "\033[33m安装已取消!\033[0m" fi elif [ -w /www -a -n "$(pidof nginx)" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "请选择面板\033[33m安装目录:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 在${CRASHDIR}/ui目录安装" echo -e " 2 在/www/clash目录安装" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo " 0 返回上级菜单" read -p "请输入对应数字 > " num @@ -1894,20 +1894,20 @@ setdb(){ fi } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m安装本地版dashboard管理面板\033[0m" echo -e "\033[32m打开管理面板的速度更快且更稳定\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "请选择面板\033[33m安装类型:\033[0m" - echo -----------------维护中------------------------ + echo "-----------------维护中------------------------" echo -e " 1 安装\033[32mzashboard面板\033[0m(约2.2mb)" echo -e " 2 安装\033[32mMetaXD面板\033[0m(约1.5mb)" echo -e " 3 安装\033[32mYacd-Meta魔改面板\033[0m(约1.7mb)" - echo ---------------已停止维护---------------------- + echo "---------------已停止维护----------------------" echo -e " 4 安装\033[32m基础面板\033[0m(约500kb)" echo -e " 5 安装\033[32mMeta基础面板\033[0m(约800kb)" echo -e " 6 安装\033[32mYacd面板\033[0m(约1.1mb)" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 9 卸载\033[33m本地面板\033[0m" echo " 0 返回上级菜单" read -p "请输入对应数字 > " num @@ -1919,55 +1919,55 @@ setdb(){ echo $update_url setconfig external_ui_url "https://raw.githubusercontent.com/juewuy/ShellCrash/update/bin/dashboard/zashboard.tar.gz" dbdir - ;; + ;; 2) db_type=meta_xd setconfig external_ui_url "https://raw.githubusercontent.com/juewuy/ShellCrash/update/bin/dashboard/meta_xd.tar.gz" dbdir - ;; + ;; 3) db_type=meta_yacd dbdir - ;; + ;; 4) db_type=clashdb dbdir - ;; + ;; 5) db_type=meta_db dbdir - ;; + ;; 6) db_type=yacd dbdir - ;; + ;; 9) read -p "确认卸载本地面板?(1/0) > " res if [ "$res" = 1 ];then rm -rf /www/clash rm -rf ${CRASHDIR}/ui rm -rf ${BINDIR}/ui - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m面板已经卸载!\033[0m" sleep 1 fi - ;; + ;; *) errornum - ;; + ;; esac } getcrt(){ #下载根证书文件 - echo ----------------------------------------------- - echo 正在连接服务器获取安装文件………… + echo "-----------------------------------------------" + echo "正在连接服务器获取安装文件…………" ${CRASHDIR}/start.sh get_bin ${TMPDIR}/ca-certificates.crt bin/fix/ca-certificates.crt if [ "$?" = "1" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m文件下载失败!\033[0m" error_down else - echo ----------------------------------------------- + echo "-----------------------------------------------" [ "$systype" = 'mi_snapshot' ] && cp -f ${TMPDIR}/ca-certificates.crt $CRASHDIR/tools #镜像化设备特殊处理 [ -f $openssldir/certs ] && rm -rf $openssldir/certs #如果certs不是目录而是文件则删除并创建目录 mkdir -p $openssldir/certs @@ -1989,11 +1989,11 @@ setcrt(){ crtdir="/etc/ssl/certs/ca-certificates.crt" fi if [ -n "$openssldir" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m安装/更新本地根证书文件(ca-certificates.crt)\033[0m" echo -e "\033[33m用于解决证书校验错误,x509报错等问题\033[0m" echo -e "\033[31m无上述问题的设备请勿使用!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" [ -f "$crtdir" ] && echo -e "\033[33m检测到系统已经存在根证书文件($crtdir)了!\033[0m\n-----------------------------------------------" read -p "是否覆盖更新?(1/0) > " res @@ -2007,7 +2007,7 @@ setcrt(){ errornum fi else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m设备可能尚未安装openssl,无法安装证书文件!\033[0m" sleep 1 fi @@ -2025,25 +2025,25 @@ setserver(){ setconfig update_url "'$update_url'" setconfig url_id $url_id setconfig release_type $release_type - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m源地址切换成功!\033[0m" } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m切换ShellCrash版本及更新源地址\033[0m" echo -e "当前版本:\033[4;33m$release_name\033[0m 当前源:\033[4;32m$url_name\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" grep -E "^1|$release_name" ${CRASHDIR}/configs/servers.list | awk '{print " "NR" "$2}' - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " a 切换至\033[32m稳定版-stable\033[0m" echo -e " b 切换至\033[36m公测版-master\033[0m" echo -e " c 切换至\033[33m开发版-dev\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " d 自定义源地址(用于本地源或自建源)" echo -e " e \033[31m版本回退\033[0m" echo -e " 0 返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应字母或数字 > " num - case $num in + case "$num" in 0) checkupdate=false ;; @@ -2077,7 +2077,7 @@ setserver(){ setserver ;; c) - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m开发版未经过妥善测试,可能依然存在大量bug!!!\033[0m" echo -e "\033[36m如果你没有足够的耐心或者测试经验,切勿使用此版本!\033[0m" echo -e "请务必加入我们的讨论组:\033[32;4mhttps://t.me/ShellClash\033[0m" @@ -2090,10 +2090,10 @@ setserver(){ setserver ;; d) - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入个人源路径 > " update_url if [ -z "$update_url" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m取消输入,返回上级菜单\033[0m" else url_id='' @@ -2102,7 +2102,7 @@ setserver(){ fi ;; e) - echo ----------------------------------------------- + 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 @@ -2118,13 +2118,13 @@ setserver(){ update_url='' saveserver else - echo ----------------------------------------------- + echo "-----------------------------------------------" errornum sleep 1 setserver fi else - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[31m版本回退信息获取失败,请尝试更换其他安装源!\033[0m" sleep 1 setserver @@ -2158,77 +2158,78 @@ checkupdate(){ rm -rf ${TMPDIR}/version_new } update(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -ne "\033[32m正在检查更新!\033[0m\r" checkupdate [ -z "$core_v" ] && core_v=$crashcore core_v_new=$(eval echo \$${crashcore}_v) echo -e "\033[30;47m欢迎使用更新功能:\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "当前目录(\033[32m${CRASHDIR}\033[0m)剩余空间:\033[36m$(dir_avail ${CRASHDIR} -h)\033[0m" [ "$(dir_avail ${CRASHDIR})" -le 5120 ] && [ "$CRASHDIR" = "$BINDIR" ] && { echo -e "\033[33m当前目录剩余空间较低,建议开启小闪存模式!\033[0m" sleep 1 } - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 更新\033[36m管理脚本 \033[33m$versionsh_l\033[0m > \033[32m$version_new \033[36m$release_type\033[0m" echo -e " 2 切换\033[33m内核文件 \033[33m$core_v\033[0m > \033[32m$core_v_new\033[0m" echo -e " 3 更新\033[32m数据库文件\033[0m > \033[32m$GeoIP_v\033[0m" echo -e " 4 安装本地\033[35mDashboard\033[0m面板" echo -e " 5 安装/更新本地\033[33m根证书文件\033[0m" echo -e " 6 查看\033[32mPAC\033[0m自动代理配置" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 7 切换\033[36m安装源\033[0m及\033[36m安装版本\033[0m" echo -e " 8 \033[32m配置自动更新\033[0m" echo -e " 9 \033[31m卸载ShellCrash\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "99 \033[36m鸣谢!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 0 返回上级菜单" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum - elif [ "$num" = 0 ]; then + case "$num" in + 0) i= - elif [ "$num" = 1 ]; then - setscripts - - elif [ "$num" = 2 ]; then - setcore - - elif [ "$num" = 3 ]; then + ;; + 1) + setscripts + ;; + 2) + setcore + ;; + 3) setgeo update - - elif [ "$num" = 4 ]; then + ;; + 4) setdb update - - elif [ "$num" = 5 ]; then - setcrt - update - - elif [ "$num" = 6 ]; then - echo ----------------------------------------------- - echo -e "PAC配置链接为:\033[30;47m http://$host:$db_port/ui/pac \033[0m" - echo -e "PAC的使用教程请参考:\033[4;32mhttps://juewuy.github.io/ehRUeewcv\033[0m" - sleep 2 - update - - elif [ "$num" = 7 ]; then - setserver - update - elif [ "$num" = 8 ]; then - . ${CRASHDIR}/task/task.sh && task_add - update - - elif [ "$num" = 9 ]; then - uninstall - exit - - elif [ "$num" = 99 ]; then - echo ----------------------------------------------- + ;; + 5) + setcrt + update + ;; + 6) + echo "-----------------------------------------------" + echo -e "PAC配置链接为:\033[30;47m http://$host:$db_port/ui/pac \033[0m" + echo -e "PAC的使用教程请参考:\033[4;32mhttps://juewuy.github.io/ehRUeewcv\033[0m" + sleep 2 + update + ;; + 7) + setserver + update + ;; + 8) + . ${CRASHDIR}/task/task.sh && task_add + update + ;; + 9) + uninstall + exit + ;; + 99) + echo "-----------------------------------------------" echo -e "感谢:\033[32mClash项目 \033[0m作者\033[36m Dreamacro\033[0m" echo -e "感谢:\033[32msing-box项目 \033[0m作者\033[36m SagerNet\033[0m 项目地址:\033[32mhttps://github.com/SagerNet/sing-box\033[0m" echo -e "感谢:\033[32mMetaCubeX项目 \033[0m作者\033[36m MetaCubeX\033[0m 项目地址:\033[32mhttps://github.com/MetaCubeX\033[0m" @@ -2238,34 +2239,34 @@ update(){ echo -e "感谢:\033[32msing-box分支项目 \033[0m作者\033[36m PuerNya\033[0m 项目地址:\033[32mhttps://github.com/PuerNya/sing-box\033[0m" echo -e "感谢:\033[32msing-box分支项目 \033[0m作者\033[36m reF1nd\033[0m 项目地址:\033[32mhttps://github.com/reF1nd/sing-box\033[0m" echo -e "感谢:\033[32mDustinWin相关项目 \033[0m作者\033[36m DustinWin\033[0m 作者地址:\033[32mhttps://github.com/DustinWin\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "特别感谢:\033[36m所有帮助及赞助过此项目的同仁们!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" sleep 2 update - else - errornum - fi + ;; + *) + errornum + ;; + esac } #新手引导 userguide(){ forwhat(){ - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;46m 欢迎使用ShellCrash新手引导! \033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m请先选择你的使用环境: \033[0m" echo -e "\033[0m(你之后依然可以在设置中更改各种配置)\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 \033[32m路由设备配置局域网透明代理\033[0m" echo -e " 2 \033[36mLinux设备仅配置本机代理\033[0m" [ -f "$CFG_PATH.bak" ] && echo -e " 3 \033[33m还原之前备份的设置\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "请输入对应数字 > " num - if [ -z "$num" ] || [ "$num" -gt 4 ];then - errornum - forwhat - elif [ "$num" = 1 ];then + case "$num" in + 1) #设置运行模式 redir_mod="混合模式" [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] && { @@ -2295,7 +2296,7 @@ userguide(){ autostart=enable #检测IP转发 if [ "$(cat /proc/sys/net/ipv4/ip_forward)" = "0" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m检测到你的设备尚未开启ip转发,局域网设备将无法正常连接网络,是否立即开启?\033[0m" read -p "是否开启?(1/0) > " res [ "$res" = 1 ] && { @@ -2306,28 +2307,34 @@ userguide(){ #禁止docker启用的net.bridge.bridge-nf-call-iptables sysctl -w net.bridge.bridge-nf-call-iptables=0 > /dev/null 2>&1 sysctl -w net.bridge.bridge-nf-call-ip6tables=0 > /dev/null 2>&1 - elif [ "$num" = 2 ];then + ;; + 2) setconfig redir_mod "Redir模式" [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ] && setconfig crashcore "clash" setconfig common_ports "未开启" setconfig firewall_area '2' - - elif [ "$num" = 3 ];then + ;; + 3) mv -f $CFG_PATH.bak $CFG_PATH echo -e "\033[32m脚本设置已还原!\033[0m" echo -e "\033[33m请重新启动脚本!\033[0m" exit 0 - fi + ;; + *) + errornum + forwhat + ;; + esac } forwhat #检测小内存模式 dir_size=$(dir_avail ${CRASHDIR}) if [ "$dir_size" -lt 10240 ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m检测到你的安装目录空间不足10M,是否开启小闪存模式?\033[0m" echo -e "\033[0m开启后核心及数据库文件将被下载到内存中,这将占用一部分内存空间\033[0m" echo -e "\033[0m每次开机后首次运行服务时都会自动的重新下载相关文件\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "是否开启?(1/0) > " res [ "$res" = 1 ] && { BINDIR=/tmp/ShellCrash @@ -2338,9 +2345,9 @@ userguide(){ openssldir="$(openssl version -d 2>&1 | awk -F '"' '{print $2}')" [ ! -d "$openssldir/certs" ] && openssldir=/etc/ssl if [ -d $openssldir/certs -a ! -f $openssldir/certs/ca-certificates.crt ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m当前设备未找到根证书文件\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "是否下载并安装根证书?(1/0) > " res [ "$res" = 1 ] && checkupdate && getcrt fi @@ -2363,7 +2370,7 @@ userguide(){ fi } if ckcmd systemctl;then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m是否开启公网访问Dashboard面板及socks服务?\033[0m" echo -e "注意当前设备必须有公网IP才能从公网正常访问" echo -e "\033[31m此功能会增加暴露风险请谨慎使用!\033[0m" @@ -2390,17 +2397,17 @@ userguide(){ . ${CRASHDIR}/task/task.sh && task_recom #小米设备软固化 if [ "$systype" = "mi_snapshot" ];then - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[33m检测到为小米路由设备,启用软固化可防止路由升级后丢失SSH\033[0m" read -p "是否启用软固化功能?(1/0) > " res [ "$res" = 1 ] && autoSSH fi #提示导入订阅或者配置文件 [ ! -s $CRASHDIR/yamls/config.yaml -a ! -s $CRASHDIR/jsons/config.json ] && { - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[32m是否导入配置文件?\033[0m(这是运行前的最后一步)" echo -e "\033[0m你必须拥有一份配置文件才能运行服务!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "现在开始导入?(1/0) > " res [ "$res" = 1 ] && inuserguide=1 && { if [ -f "$CRASHDIR"/v2b_api.sh ];then @@ -2413,9 +2420,9 @@ userguide(){ } } #回到主界面 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m很好!现在只需要执行启动就可以愉快的使用了!\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" read -p "立即启动服务?(1/0) > " res [ "$res" = 1 ] && start_core && sleep 2 main_menu @@ -2423,22 +2430,22 @@ userguide(){ #测试菜单 debug(){ echo "$crashcore" | grep -q 'singbox' && config_tmp=$TMPDIR/jsons || config_tmp=$TMPDIR/config.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[36m注意:Debug运行均会停止原本的内核服务\033[0m" echo -e "后台运行日志地址:\033[32m$TMPDIR/debug.log\033[0m" echo -e "如长时间运行后台监测,日志等级推荐error!防止文件过大!" echo -e "你也可以通过:\033[33mcrash -s debug 'warning'\033[0m 命令使用其他日志等级" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 1 仅测试\033[32m$config_tmp\033[0m配置文件可用性" echo -e " 2 前台运行\033[32m$config_tmp\033[0m配置文件,不配置防火墙劫持(\033[33m使用Ctrl+C手动停止\033[0m)" echo -e " 3 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[31merror\033[0m" echo -e " 4 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[32minfo\033[0m" echo -e " 5 后台运行完整启动流程,并配置防火墙劫持,日志等级:\033[33mdebug\033[0m" echo -e " 6 后台运行完整启动流程,并配置防火墙劫持,且将错误日志打印到闪存:\033[32m$CRASHDIR/debug.log\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e " 8 后台运行完整启动流程,输出执行错误并查找上下文,之后关闭进程" [ -s $TMPDIR/jsons/inbounds.json ] && echo -e " 9 将\033[32m$config_tmp\033[0m下json文件合并为$TMPDIR/debug.json" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo " 0 返回上级目录!" read -p "请输入对应数字 > " num case "$num" in @@ -2454,7 +2461,7 @@ debug(){ ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml fi rm -rf ${TMPDIR}/CrashCore - echo ----------------------------------------------- + echo "-----------------------------------------------" exit ;; 2) @@ -2462,7 +2469,7 @@ debug(){ $CRASHDIR/start.sh bfstart $COMMAND rm -rf ${TMPDIR}/CrashCore - echo ----------------------------------------------- + echo "-----------------------------------------------" exit ;; 3) @@ -2499,61 +2506,62 @@ debug(){ } testcommand(){ echo "$crashcore" | grep -q 'singbox' && config_path=${JSONSDIR}/config.json || config_path=${YAMLSDIR}/config.yaml - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "\033[30;47m这里是测试命令菜单\033[0m" echo -e "\033[33m如遇问题尽量运行相应命令后截图提交issue或TG讨论组\033[0m" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo " 1 Debug模式运行内核" echo " 2 查看系统DNS端口(:53)占用 " echo " 3 测试ssl加密(aes-128-gcm)跑分" echo " 4 查看ShellCrash相关路由规则" echo " 5 查看内核配置文件前40行" echo " 6 测试代理服务器连通性(google.tw)" - echo ----------------------------------------------- + echo "-----------------------------------------------" echo " 0 返回上级目录!" read -p "请输入对应数字 > " num - if [ -z "$num" ]; then - errornum + case "$num" in + 0) main_menu - elif [ "$num" = 0 ]; then - main_menu - elif [ "$num" = 1 ]; then + ;; + 1) debug testcommand - elif [ "$num" = 2 ]; then - echo ----------------------------------------------- + ;; + 2) + echo "-----------------------------------------------" netstat -ntulp |grep 53 - echo ----------------------------------------------- + echo "-----------------------------------------------" echo -e "可以使用\033[44m netstat -ntulp |grep xxx \033[0m来查询任意(xxx)端口" exit; - elif [ "$num" = 3 ]; then - echo ----------------------------------------------- + ;; + 3) + echo "-----------------------------------------------" openssl speed -multi 4 -evp aes-128-gcm - echo ----------------------------------------------- + echo "-----------------------------------------------" exit; - elif [ "$num" = 4 ]; then - + ;; + 4) if [ "$firewall_mod" = "nftables" ];then nft list table inet shellcrash else [ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 -o "$vm_redir" = "已开启" ] && { - echo ----------------Redir+DNS--------------------- + echo "----------------Redir+DNS---------------------" iptables -t nat -L PREROUTING --line-numbers iptables -t nat -L shellcrash_dns --line-numbers [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && iptables -t nat -L shellcrash --line-numbers [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { - echo ----------------Tun/Tproxy------------------- + echo "----------------Tun/Tproxy-------------------" iptables -t mangle -L PREROUTING --line-numbers iptables -t mangle -L shellcrash_mark --line-numbers } } [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && { - echo -------------OUTPUT-Redir+DNS---------------- + echo "-------------OUTPUT-Redir+DNS----------------" iptables -t nat -L OUTPUT --line-numbers iptables -t nat -L shellcrash_dns_out --line-numbers [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && iptables -t nat -L shellcrash_out --line-numbers [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { - echo ------------OUTPUT-Tun/Tproxy--------------- + echo "------------OUTPUT-Tun/Tproxy---------------" iptables -t mangle -L OUTPUT --line-numbers iptables -t mangle -L shellcrash_mark_out --line-numbers } @@ -2561,46 +2569,49 @@ testcommand(){ [ "$ipv6_redir" = "已开启" ] && { [ "$firewall_area" = 1 -o "$firewall_area" = 3 ] && { ip6tables -t nat -L >/dev/null 2>&1 && { - echo -------------IPV6-Redir+DNS------------------- + echo "-------------IPV6-Redir+DNS-------------------" ip6tables -t nat -L PREROUTING --line-numbers ip6tables -t nat -L shellcrashv6_dns --line-numbers [ -n "$(echo $redir_mod | grep -E 'Redir模式|混合模式')" ] && ip6tables -t nat -L shellcrashv6 --line-numbers } [ -n "$(echo $redir_mod | grep -E 'Tproxy模式|混合模式|Tun模式')" ] && { - echo -------------IPV6-Tun/Tproxy------------------ + echo "-------------IPV6-Tun/Tproxy------------------" ip6tables -t mangle -L PREROUTING --line-numbers ip6tables -t mangle -L shellcrashv6_mark --line-numbers } } } [ "$vm_redir" = "已开启" ] && { - echo -------------vm-Redir------------------- + echo "-------------vm-Redir-------------------" iptables -t nat -L shellcrash_vm --line-numbers iptables -t nat -L shellcrash_vm_dns --line-numbers } fi exit; - elif [ "$num" = 5 ]; then - echo ----------------------------------------------- + ;; + 5) + echo "-----------------------------------------------" sed -n '1,40p' ${config_path} - echo ----------------------------------------------- + echo "-----------------------------------------------" exit; - elif [ "$num" = 6 ]; then + ;; + 6) echo "注意:依赖curl(不支持wget),且测试结果不保证一定准确!" delay=`curl -kx ${authentication}@127.0.0.1:$mix_port -o /dev/null -s -w '%{time_starttransfer}' 'https://google.tw' & { sleep 3 ; kill $! >/dev/null 2>&1 & }` > /dev/null 2>&1 delay=`echo |awk "{print $delay*1000}"` > /dev/null 2>&1 - echo ----------------------------------------------- + echo "-----------------------------------------------" if [ `echo ${#delay}` -gt 1 ];then echo -e "\033[32m连接成功!响应时间为:"$delay" ms\033[0m" else echo -e "\033[31m连接超时!请重试或检查节点配置!\033[0m" fi main_menu - - else + ;; + *) errornum main_menu - fi + ;; + esac } case "$1" in