~脚本进行大量拆分和优化

This commit is contained in:
juewuy
2025-12-25 15:50:58 +08:00
parent e62f485df4
commit 647b52e016
49 changed files with 1948 additions and 2449 deletions

View File

@@ -3,9 +3,9 @@
101#$CRASHDIR/start.sh start#启动ShellCrash服务
102#$CRASHDIR/start.sh stop#停止ShellCrash服务
103#$CRASHDIR/start.sh restart#重启ShellCrash服务
104#$CRASHDIR/start.sh update_config#更新在线订阅并重启服务
105#$CRASHDIR/start.sh hotupdate#热更新在线订阅(不重启)
106#$CRASHDIR/start.sh web_save#自动保存面板配置
104#$CRASHDIR/task/task.sh update_config#更新在线订阅并重启服务
105#$CRASHDIR/task/task.sh hotupdate#热更新在线订阅(不重启)
106#$CRASHDIR/task/task.sh web_save_auto#自动保存面板配置
107#$CRASHDIR/task/task.sh ntp#自动同步ntp时间
111#$CRASHDIR/task/task.sh update_core#自动更新内核

View File

@@ -1,161 +1,6 @@
#!/bin/sh
# Copyright (C) Juewuy
setdir() {
dir_avail() {
df $2 $1 | awk '{ for(i=1;i<=NF;i++){ if(NR==1){ arr[i]=$i; }else{ arr[i]=arr[i]" "$i; } } } END{ for(i=1;i<=NF;i++){ print arr[i]; } }' | grep -E 'Ava|可用' | awk '{print $2}'
}
set_usb_dir() {
echo -e "请选择安装目录"
du -hL /mnt | awk '{print " "NR" "$2" "$1}'
read -p "请输入相应数字 > " num
dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p)
if [ -z "$dir" ]; then
echo -e "\033[31m输入错误请重新设置\033[0m"
set_usb_dir
fi
}
set_asus_dir() {
echo -e "请选择U盘目录"
du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}'
read -p "请输入相应数字 > " num
dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p)
if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then
echo -e "\033[31m未找到下载大师自启文件$dir/asusware.arm/etc/init.d/S50downloadmaster请检查设置\033[0m"
set_asus_dir
fi
}
set_cust_dir() {
echo "-----------------------------------------------"
echo "可用路径 剩余空间:"
df -h | awk '{print $6,$4}' | sed 1d
echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!"
read -p "请输入自定义路径 > " dir
if [ "$(dir_avail $dir)" = 0 ] || [ -n "$(echo $dir | grep -E 'tmp|opt|sys')" ]; then
echo "\033[31m路径错误请重新设置\033[0m"
set_cust_dir
fi
}
echo "-----------------------------------------------"
if [ -n "$systype" ]; then
[ "$systype" = "Padavan" ] && dir=/etc/storage
[ "$systype" = "mi_snapshot" ] && {
echo -e "\033[33m检测到当前设备为小米官方系统请选择安装位置\033[0m"
[ -d /data ] && $echo " 1 安装到 /data 目录,剩余空间:$(dir_avail /data -h)(支持软固化功能)"
[ -d /userdisk ] && $echo " 2 安装到 /userdisk 目录,剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)"
[ -d /data/other_vol ] && $echo " 3 安装到 /data/other_vol 目录,剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)"
$echo " 4 安装到自定义目录(不推荐,不明勿用!)"
echo " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
case "$num" in
1)
dir=/data
;;
2)
dir=/userdisk
;;
3)
dir=/data/other_vol
;;
4)
set_cust_dir
;;
*)
exit 1
;;
esac
}
[ "$systype" = "asusrouter" ] && {
echo -e "\033[33m检测到当前设备为华硕固件请选择安装方式\033[0m"
echo -e " 1 基于USB设备安装(限23年9月之前固件须插入\033[31m任意\033[0mUSB设备)"
echo -e " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)"
echo -e " 3 基于U盘+下载大师安装(支持所有固件限ARM设备须插入U盘或移动硬盘)"
echo -e " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
case "$num" in
1)
read -p "将脚本安装到USB存储/系统闪存?(1/0) > " res
[ "$res" = "1" ] && set_usb_dir || dir=/jffs
usb_status=1
;;
2)
echo -e "如无法正常开机启动请重新使用USB方式安装"
sleep 2
dir=/jffs
;;
3)
echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!"
sleep 2
set_asus_dir
;;
*)
exit 1
;;
esac
}
[ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt
else
echo -e "\033[33m安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m"
echo -e " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)"
echo -e " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)"
echo -e " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)"
echo -e " 4 在\033[32m外置存储\033[0m中安装"
echo -e " 5 手动设置安装目录"
echo -e " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
#设置目录
case "$num" in
1)
dir=/etc
;;
2)
dir=/usr/share
;;
3)
dir=~/.local/share
mkdir -p ~/.config/systemd/user
;;
4)
set_usb_dir
;;
5)
echo "-----------------------------------------------"
echo "可用路径 剩余空间:"
df -h | awk '{print $6,$4}' | sed 1d
echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!"
read -p "请输入自定义路径 > " dir
if [ -z "$dir" ]; then
echo -e "\033[31m路径错误请重新设置\033[0m"
setdir
fi
;;
*)
echo "安装已取消"
exit 1
;;
esac
fi
if [ ! -w $dir ]; then
echo -e "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir
else
echo -e "目标目录\033[32m$dir\033[0m空间剩余$(dir_avail $dir -h)"
read -p "确认安装?(1/0) > " res
[ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir
fi
}
setconfig() { #脚本配置工具
#参数1代表变量名参数2代表变量值,参数3即文件路径
[ -z "$3" ] && configpath="$CRASHDIR"/configs/ShellCrash.cfg || configpath="${3}"
if grep -q "^${1}=" "$configpath"; then
sed -i "s#^${1}=.*#${1}=${2}#g" "$configpath"
else
printf '%s=%s\n' "$1" "$2" >>"$configpath"
fi
}
#特殊固件识别及标记
[ -f "/etc/storage/started_script.sh" ] && { #老毛子固件
systype=Padavan
@@ -176,20 +21,25 @@ grep -qE '/(docker|lxc|kubepods|crio|containerd)/' /proc/1/cgroup || [ -f /run/.
#检查环境变量
[ "$systype" = 'container' ] && CRASHDIR='/etc/ShellCrash'
[ -z "$CRASHDIR" ] && [ -n "$clashdir" ] && CRASHDIR="$clashdir"
[ -z "$CRASHDIR" ] && [ -d /tmp/SC_tmp ] && setdir
[ -z "$CRASHDIR" ] && [ -d /tmp/SC_tmp ] && . /tmp/SC_tmp/menus/set_crashdir.sh && set_crashdir
#移动文件
mkdir -p ${CRASHDIR}
mv -f /tmp/SC_tmp/* ${CRASHDIR} 2>/dev/null
mkdir -p "$CRASHDIR"
rm -rf /tmp/SC_tmp/menus/set_crashdir.sh
mv -f /tmp/SC_tmp/* "$CRASHDIR" 2>/dev/null
##############################
#注意目录变更
CFG_PATH="$CRASHDIR"/configs/ShellCrash.cfg
. "$CRASHDIR"/libs/set_config.sh
. "$CRASHDIR"/libs/set_profile.sh
#初始化
mkdir -p ${CRASHDIR}/configs
[ -f "${CRASHDIR}/configs/ShellCrash.cfg" ] || echo '#ShellCrash配置文件不明勿动' >${CRASHDIR}/configs/ShellCrash.cfg
mkdir -p "$CRASHDIR"/configs
[ -f "$CFG_PATH" ] || echo '#ShellCrash配置文件不明勿动' >"$CFG_PATH"
#判断系统类型写入不同的启动文件
[ -w /usr/lib/systemd/system ] && sysdir=/usr/lib/systemd/system
[ -w /etc/systemd/system ] && sysdir=/etc/systemd/system
if [ -f /etc/rc.common -a "$(cat /proc/1/comm)" = "procd" ]; then
#设为init.d方式启动
cp -f ${CRASHDIR}/starts/shellcrash.procd /etc/init.d/shellcrash
cp -f "$CRASHDIR"/starts/shellcrash.procd /etc/init.d/shellcrash
chmod 755 /etc/init.d/shellcrash
elif [ -n "$sysdir" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ]; then
#创建shellcrash用户
@@ -203,45 +53,45 @@ elif [ -n "$sysdir" -a "$USER" = "root" -a "$(cat /proc/1/comm)" = "systemd" ];
echo "shellcrash:x:0:7890::/home/shellcrash:/bin/sh" >>/etc/passwd
fi
#配置systemd
mv -f ${CRASHDIR}/starts/shellcrash.service $sysdir/shellcrash.service 2>/dev/null
sed -i "s%/etc/ShellCrash%$CRASHDIR%g" $sysdir/shellcrash.service
mv -f "$CRASHDIR"/starts/shellcrash.service "$sysdir"/shellcrash.service 2>/dev/null
sed -i "s%/etc/ShellCrash%$CRASHDIR%g" "$sysdir"/shellcrash.service
systemctl daemon-reload
rm -rf ${CRASHDIR}/starts/shellcrash.procd
rm -rf "$CRASHDIR"/starts/shellcrash.procd
elif rc-status -r >/dev/null 2>&1; then
#设为openrc方式启动
mv -f ${CRASHDIR}/starts/shellcrash.openrc /etc/init.d/shellcrash
mv -f "$CRASHDIR"/starts/shellcrash.openrc /etc/init.d/shellcrash
chmod 755 /etc/init.d/shellcrash
rm -rf ${CRASHDIR}/starts/shellcrash.procd
rm -rf "$CRASHDIR"/starts/shellcrash.procd
else
#设为保守模式启动
setconfig start_old 已开启
rm -rf ${CRASHDIR}/starts/shellcrash.procd
rm -rf "$CRASHDIR"/starts/shellcrash.procd
fi
rm -rf ${CRASHDIR}/starts/shellcrash.service
rm -rf ${CRASHDIR}/starts/shellcrash.openrc
rm -rf "$CRASHDIR"/starts/shellcrash.service
rm -rf "$CRASHDIR"/starts/shellcrash.openrc
#修饰文件及版本号
command -v bash >/dev/null 2>&1 && shtype=bash
[ -x /bin/ash ] && shtype=ash
for file in start.sh menus/5-task.sh menu.sh; do
sed -i "s|/bin/sh|/bin/$shtype|" ${CRASHDIR}/${file} 2>/dev/null
chmod +x ${CRASHDIR}/${file} 2>/dev/null
for file in start.sh starts/bfstart.sh starts/afstart.sh menu.sh menus/task_cmd.sh; do
sed -i "s|/bin/sh|/bin/$shtype|" "$CRASHDIR/$file" 2>/dev/null
chmod +x "$CRASHDIR/$file" 2>/dev/null
done
setconfig versionsh_l $version
#生成用于执行启动服务的变量文件
[ ! -f ${CRASHDIR}/configs/command.env ] && {
[ ! -f "$CRASHDIR"/configs/command.env ] && {
TMPDIR='/tmp/ShellCrash'
BINDIR=${CRASHDIR}
touch ${CRASHDIR}/configs/command.env
setconfig TMPDIR ${TMPDIR} ${CRASHDIR}/configs/command.env
setconfig BINDIR ${BINDIR} ${CRASHDIR}/configs/command.env
BINDIR="$CRASHDIR"
touch "$CRASHDIR"/configs/command.env
setconfig TMPDIR "$TMPDIR" "$CRASHDIR"/configs/command.env
setconfig BINDIR "$BINDIR" "$CRASHDIR"/configs/command.env
}
if [ -n "$(grep 'crashcore=singbox' ${CRASHDIR}/configs/ShellCrash.cfg)" ]; then
if [ -n "$(grep 'crashcore=singbox' "$CFG_PATH")" ]; then
COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"'
else
COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"'
fi
setconfig COMMAND "$COMMAND" ${CRASHDIR}/configs/command.env
setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env
#设置防火墙执行模式
grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || {
firewall_mod=iptables
@@ -254,13 +104,6 @@ grep -q 'firewall_mod' "$CRASHDIR/configs/ShellClash.cfg" 2>/dev/null || {
[ -w /opt/etc/profile ] && profile=/opt/etc/profile
[ -w /jffs/configs/profile.add ] && profile=/jffs/configs/profile.add
[ -z "$profile" ] && profile=/etc/profile
set_profile() {
[ -z "$my_alias" ] && my_alias=crash
sed -i "/ShellCrash\/menu.sh/"d "$1"
echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量
sed -i '/export CRASHDIR=*/'d "$1"
echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量
}
if [ -n "$profile" ]; then
set_profile "$profile"
#适配zsh环境变量
@@ -272,17 +115,18 @@ else
fi
#梅林/Padavan额外设置
[ -n "$initdir" ] && {
sed -i '/ShellCrash初始化/'d $initdir
touch $initdir
echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >>$initdir
chmod a+rx $initdir 2>/dev/null
setconfig initdir $initdir
touch "$initdir"
sed -i '/ShellCrash初始化/'d "$initdir"
echo "$CRASHDIR/starts/general_init.sh & #ShellCrash初始化脚本" >>"$initdir"
chmod 755 "$CRASHDIR"/starts/general_init.sh
chmod a+rx "$initdir" 2>/dev/null
setconfig initdir "$initdir"
}
#Padavan额外设置
[ -f "/etc/storage/started_script.sh" ] && mount -t tmpfs -o remount,rw,size=45M tmpfs /tmp #增加/tmp空间以适配新的内核压缩方式
#镜像化OpenWrt(snapshot)额外设置
if [ "$systype" = "mi_snapshot" -o "$systype" = "ng_snapshot" ]; then
chmod 755 ${CRASHDIR}/starts/snapshot_init.sh
chmod 755 "$CRASHDIR"/starts/snapshot_init.sh
uci delete firewall.ShellClash 2>/dev/null
uci delete firewall.ShellCrash 2>/dev/null
uci set firewall.ShellCrash=include
@@ -291,11 +135,11 @@ if [ "$systype" = "mi_snapshot" -o "$systype" = "ng_snapshot" ]; then
uci set firewall.ShellCrash.enabled='1'
uci commit firewall
else
rm -rf ${CRASHDIR}/starts/snapshot_init.sh
rm -rf "$CRASHDIR"/starts/snapshot_init.sh
fi
#华硕USB启动额外设置
[ "$usb_status" = "1" ] && {
echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >${CRASHDIR}/asus_usb_mount.sh
echo "$CRASHDIR/start.sh init & #ShellCrash初始化脚本" >"$CRASHDIR"/asus_usb_mount.sh
nvram set script_usbmount="$CRASHDIR/asus_usb_mount.sh"
nvram commit
}
@@ -325,57 +169,57 @@ setconfig systype $systype
rm -rf /tmp/*rash*gz
rm -rf /tmp/SC_tmp
#转换&清理旧版本文件
mkdir -p ${CRASHDIR}/yamls
mkdir -p ${CRASHDIR}/jsons
mkdir -p ${CRASHDIR}/tools
mkdir -p ${CRASHDIR}/task
mkdir -p ${CRASHDIR}/ruleset
mkdir -p "$CRASHDIR"/yamls
mkdir -p "$CRASHDIR"/jsons
mkdir -p "$CRASHDIR"/tools
mkdir -p "$CRASHDIR"/task
mkdir -p "$CRASHDIR"/ruleset
for file in config.yaml.bak user.yaml proxies.yaml proxy-groups.yaml rules.yaml others.yaml; do
mv -f ${CRASHDIR}/$file ${CRASHDIR}/yamls/$file 2>/dev/null
mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/yamls/"$file" 2>/dev/null
done
[ ! -L ${CRASHDIR}/config.yaml ] && mv -f ${CRASHDIR}/config.yaml ${CRASHDIR}/yamls/config.yaml 2>/dev/null
[ ! -L "$CRASHDIR"/config.yaml ] && mv -f "$CRASHDIR"/config.yaml "$CRASHDIR"/yamls/config.yaml 2>/dev/null
for file in fake_ip_filter mac web_save servers.list fake_ip_filter.list fallback_filter.list singbox_providers.list clash_providers.list; do
mv -f ${CRASHDIR}/$file ${CRASHDIR}/configs/$file 2>/dev/null
mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/configs/"$file" 2>/dev/null
done
#配置文件改名
mv -f ${CRASHDIR}/configs/ShellClash.cfg ${CRASHDIR}/configs/ShellCrash.cfg 2>/dev/null
mv -f "$CRASHDIR"/configs/ShellClash.cfg "$CFG_PATH" 2>/dev/null
#数据库改名
mv -f ${CRASHDIR}/geosite.dat ${CRASHDIR}/GeoSite.dat 2>/dev/null
mv -f ${CRASHDIR}/ruleset/geosite-cn.srs ${CRASHDIR}/ruleset/cn.srs 2>/dev/null
mv -f ${CRASHDIR}/ruleset/geosite-cn.mrs ${CRASHDIR}/ruleset/cn.mrs 2>/dev/null
mv -f "$CRASHDIR"/geosite.dat "$CRASHDIR"/GeoSite.dat 2>/dev/null
mv -f "$CRASHDIR"/ruleset/geosite-cn.srs "$CRASHDIR"/ruleset/cn.srs 2>/dev/null
mv -f "$CRASHDIR"/ruleset/geosite-cn.mrs "$CRASHDIR"/ruleset/cn.mrs 2>/dev/null
#数据库移动
mv -f ${CRASHDIR}/*.srs ${CRASHDIR}/ruleset/ 2>/dev/null
mv -f ${CRASHDIR}/*.mrs ${CRASHDIR}/ruleset/ 2>/dev/null
mv -f "$CRASHDIR"/*.srs "$CRASHDIR"/ruleset/ 2>/dev/null
mv -f "$CRASHDIR"/*.mrs "$CRASHDIR"/ruleset/ 2>/dev/null
#内核改名
mv -f ${CRASHDIR}/clash ${CRASHDIR}/CrashCore 2>/dev/null
mv -f "$CRASHDIR"/clash "$CRASHDIR"/CrashCore 2>/dev/null
#内核压缩
[ -f ${CRASHDIR}/CrashCore ] && tar -zcf ${CRASHDIR}/CrashCore.tar.gz -C ${CRASHDIR} CrashCore
[ -f "$CRASHDIR"/CrashCore ] && tar -zcf "$CRASHDIR"/CrashCore.tar.gz -C "$CRASHDIR" CrashCore
for file in dropbear_rsa_host_key authorized_keys tun.ko ShellDDNS.sh; do
mv -f ${CRASHDIR}/$file ${CRASHDIR}/tools/$file 2>/dev/null
mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/tools/"$file" 2>/dev/null
done
for file in cron task.list; do
mv -f ${CRASHDIR}/$file ${CRASHDIR}/task/$file 2>/dev/null
mv -f "$CRASHDIR"/"$file" "$CRASHDIR"/task/"$file" 2>/dev/null
done
mv -f "$CRASHDIR"/menus/task_cmd.sh "$CRASHDIR"/task/task.sh 2>/dev/null
#旧版文件清理
userdel shellclash >/dev/null 2>&1
sed -i '/shellclash/d' /etc/passwd
sed -i '/shellclash/d' /etc/group
rm -rf /etc/init.d/clash
rm -rf ${CRASHDIR}/rules
rm -rf "$CRASHDIR/task/task.sh"
rm -rf "$CRASHDIR"/rules
[ "$systype" = "mi_snapshot" -a "$CRASHDIR" != '/data/clash' ] && rm -rf /data/clash
for file in CrashCore clash.sh getdate.sh core.new clashservice log mark? mark.bak; do
rm -rf "$CRASHDIR/$file"
done
#旧版变量改名
sed -i "s/clashcore/crashcore/g" $configpath
sed -i "s/clash_v/core_v/g" $configpath
sed -i "s/clash.meta/meta/g" $configpath
sed -i "s/ShellClash/ShellCrash/g" $configpath
sed -i "s/cpucore=armv8/cpucore=arm64/g" $configpath
sed -i "s/redir_mod=Nft基础/redir_mod=Redir模式/g" $configpath
sed -i "s/redir_mod=Nft混合/redir_mod=Tproxy模式/g" $configpath
sed -i "s/redir_mod=Tproxy混合/redir_mod=Tproxy模式/g" $configpath
sed -i "s/redir_mod=纯净模式/firewall_area=4/g" $configpath
sed -i "s/clashcore/crashcore/g" "$CFG_PATH"
sed -i "s/clash_v/core_v/g" "$CFG_PATH"
sed -i "s/clash.meta/meta/g" "$CFG_PATH"
sed -i "s/ShellClash/ShellCrash/g" "$CFG_PATH"
sed -i "s/cpucore=armv8/cpucore=arm64/g" "$CFG_PATH"
sed -i "s/redir_mod=Nft基础/redir_mod=Redir模式/g" "$CFG_PATH"
sed -i "s/redir_mod=Nft混合/redir_mod=Tproxy模式/g" "$CFG_PATH"
sed -i "s/redir_mod=Tproxy混合/redir_mod=Tproxy模式/g" "$CFG_PATH"
sed -i "s/redir_mod=纯净模式/firewall_area=4/g" "$CFG_PATH"
echo -e "\033[32m脚本初始化完成,请输入\033[30;47m $my_alias \033[0;33m命令开始使用\033[0m"

View File

@@ -0,0 +1,14 @@
check_cpucore(){ #自动获取内核架构
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="armv5"
[ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && [ ! -d /jffs ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="arm64"
[ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="386"
[ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="amd64"
if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ];then
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}') #通过判断大小端判断mips或mipsle
[ "$mipstype" = "0" ] && cpucore="mips-softfloat" || cpucore="mipsle-softfloat"
fi
[ -n "$cpucore" ] && setconfig cpucore $cpucore
}

View File

@@ -0,0 +1,8 @@
if echo "$crashcore" | grep -q 'singbox'; then
target=singbox
format=json
else
target=clash
format=yaml
fi
core_config="$CRASHDIR/${format}s/config.$format"

View File

@@ -0,0 +1,80 @@
[ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容
core_unzip() { #$1:需要解压的文件 $2:目标文件名
if echo "$1" |grep -q 'tar.gz$' ;then
[ "$BINDIR" = "$TMPDIR" ] && rm -rf "$TMPDIR"/CrashCore #小闪存模式防止空间不足
[ -n "$(tar --help 2>&1 | grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容
mkdir -p "$TMPDIR"/core_tmp
tar -zxf "$1" ${tar_para} -C "$TMPDIR"/core_tmp/
for file in $(find "$TMPDIR"/core_tmp $find_para 2>/dev/null); do
[ -f "$file" ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|pre)')" ] && mv -f "$file" "$TMPDIR"/"$2"
done
rm -rf "$TMPDIR"/core_tmp
elif echo "$1" |grep -q '.gz$' ;then
gunzip -c "$1" > "$TMPDIR"/"$2"
elif echo "$1" |grep -q '.upx$' ;then
ln -sf "$1" "$TMPDIR"/"$2"
else
mv -f "$1" "$TMPDIR"/"$2"
fi
chmod +x "$TMPDIR"/"$2"
}
core_find(){
if [ ! -f "$TMPDIR"/CrashCore ];then
core_dir=$(find "$BINDIR"/CrashCore.* $find_para 2>/dev/null)
[ -n "$core_dir" ] && core_unzip "$core_dir" CrashCore
fi
}
core_check(){
[ -n "$(pidof CrashCore)" ] && "$CRASHDIR"/start.sh stop #停止内核服务防止内存不足
core_unzip "$1" core_new
sbcheck=$(echo "$crashcore" | grep 'singbox')
v=''
if [ -n "$sbcheck" ] && "$TMPDIR"/core_new -h 2>&1 | grep -q 'sing-box'; then
v=$("$TMPDIR"/core_new version 2>/dev/null | grep version | awk '{print $3}')
COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"'
elif [ -z "$sbcheck" ] && "$TMPDIR"/core_new -h 2>&1 | grep -q '\-t';then
v=$("$TMPDIR"/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //')
COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"'
fi
if [ -z "$v" ]; then
rm -rf "$TMPDIR"/core_new
rm -rf "$1"
return 2
else
rm -f "$BINDIR"/CrashCore.tar.gz "$BINDIR"/CrashCore.gz "$BINDIR"/CrashCore.upx
mv -f "$TMPDIR"/core_new "$TMPDIR"/CrashCore
if [ -f "$1" ];then
mv -f "$1" "$BINDIR/CrashCore.${zip_type}"
else
gzip -c "$TMPDIR"/CrashCore > "$BINDIR"/CrashCore.gz
fi
core_v="$v"
setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env && . "$CRASHDIR"/configs/command.env
setconfig crashcore "$crashcore"
setconfig core_v "$core_v"
setconfig custcorelink "$custcorelink"
return 0
fi
}
core_webget(){
. "$CRASHDIR"/libs/web_get_bin.sh
. "$CRASHDIR"/libs/check_target.sh
if [ -z "$custcorelink" ];then
[ -z "$zip_type" ] && zip_type='tar.gz'
get_bin "$TMPDIR/CrashCore.${zip_type}" "bin/$crashcore/${target}-linux-${cpucore}.${zip_type}"
else
zip_type=$(echo "$custcorelink" | grep -oE 'tar.gz$')
[ -z "$zip_type" ] && zip_type=$(echo "$custcorelink" | grep -oE 'gz$')
[ -n "$zip_type" ] && webget "$TMPDIR/CrashCore.${zip_type}" "$custcorelink"
fi
#校验内核
if [ "$?" = 0 ];then
core_check "$TMPDIR/CrashCore.${zip_type}"
else
rm -rf "$TMPDIR/CrashCore.${zip_type}"
return 1
fi
}

View File

@@ -0,0 +1,11 @@
. "$CRASHDIR"/configs/command.env >/dev/null 2>&1
. "$CRASHDIR"/configs/ShellCrash.cfg
[ -z "$mix_port" ] && mix_port=7890
[ -z "$redir_port" ] && redir_port=7892
[ -z "$tproxy_port" ] && tproxy_port=7893
[ -z "$db_port" ] && db_port=9999
[ -z "$dns_port" ] && dns_port=1053
[ -z "$fwmark" ] && fwmark=$redir_port
routing_mark=$((fwmark + 2))
[ -z "$table" ] && table=100

View File

@@ -1,6 +1,7 @@
#日志工具
#$1日志内容$2显示颜色$3是否推送
logger() {
TMPDIR=/tmp/ShellCrash
[ -n "$2" -a "$2" != 0 ] && echo -e "\033[$2m$1\033[0m"
log_text="$(date "+%G-%m-%d_%H:%M:%S")~$1"
echo "$log_text" >>"$TMPDIR"/ShellCrash.log

27
scripts/libs/set_cron.sh Normal file
View File

@@ -0,0 +1,27 @@
croncmd() { #定时任务工具
if [ -n "$(crontab -h 2>&1 | grep '\-l')" ]; then
crontab "$1"
else
crondir="$(crond -h 2>&1 | grep -oE 'Default:.*' | awk -F ":" '{print $2}')"
[ ! -w "$crondir" ] && crondir="/etc/storage/cron/crontabs"
[ ! -w "$crondir" ] && crondir="/var/spool/cron/crontabs"
[ ! -w "$crondir" ] && crondir="/var/spool/cron"
if [ -w "$crondir" ]; then
[ "$1" = "-l" ] && cat "$crondir"/"$USER" 2>/dev/null
[ -f "$1" ] && cat "$1" >"$crondir"/"$USER"
else
echo "找不到可用的crond或者crontab应用No available crond or crontab application can be found!"
fi
fi
}
cronset() { #定时任务设置
# 参数1代表要移除的关键字,参数2代表要添加的任务语句
tmpcron="$TMPDIR"/cron_tmp
croncmd -l >"$tmpcron" 2>/dev/null
sed -i "/$1/d" "$tmpcron"
sed -i '/^$/d' "$tmpcron"
echo "$2" >>"$tmpcron"
croncmd "$tmpcron"
rm -f "$tmpcron"
}

View File

@@ -0,0 +1,8 @@
set_profile() {
[ -z "$my_alias" ] && my_alias=crash
sed -i "/ShellCrash\/menu.sh/"d "$1"
echo "alias ${my_alias}=\"$shtype $CRASHDIR/menu.sh\"" >>"$1" #设置快捷命令环境变量
sed -i '/export CRASHDIR=*/'d "$1"
echo "export CRASHDIR=\"$CRASHDIR\"" >>"$1" #设置路径环境变量
}

View File

@@ -3,6 +3,6 @@ setproxy(){
[ -n "$(pidof CrashCore)" ] && {
[ -n "$authentication" ] && auth="$authentication@" || auth=""
[ -z "$mix_port" ] && mix_port=7890
export https_proxy="http://${auth}127.0.0.1:$mix_port"
export all_proxy="http://${auth}127.0.0.1:$mix_port"
}
}

View File

@@ -0,0 +1,10 @@
i=1
while [ -z "$test" -a "$i" -lt 30 ]; do
sleep 1
if curl --version >/dev/null 2>&1; then
test=$(curl -s -H "Authorization: Bearer $secret" http://127.0.0.1:${db_port}/proxies | grep -o proxies)
else
test=$(wget -q --header="Authorization: Bearer $secret" -O - http://127.0.0.1:${db_port}/proxies | grep -o proxies)
fi
i=$((i + 1))
done

15
scripts/libs/urlencode.sh Normal file
View File

@@ -0,0 +1,15 @@
urlencode() {
LC_ALL=C
printf '%s' "$1" \
| hexdump -v -e '/1 "%02X\n"' \
| while read -r hex; do
case "$hex" in
2D|2E|5F|7E|3[0-9]|4[1-9A-F]|5[0-9A]|6[1-9A-F]|7[0-9A-E])
printf "\\$(printf '%03o' "0x$hex")"
;;
*)
printf "%%%s" "$hex"
;;
esac
done
}

View File

@@ -3,43 +3,43 @@
webget(){
if pidof CrashCore >/dev/null; then
setproxy #设置临时代理
url=$(printf '%s\n' "$3" |
url=$(printf '%s\n' "$2" |
sed -e 's#https://.*jsdelivr.net/gh/juewuy/ShellCrash[@|/]#https://raw.githubusercontent.com/juewuy/ShellCrash/#' \
-e 's#https://gh.jwsc.eu.org/#https://raw.githubusercontent.com/juewuy/ShellCrash/#')
else
url=$(printf '%s\n' "$3" |
url=$(printf '%s\n' "$2" |
sed 's#https://raw.githubusercontent.com/juewuy/ShellCrash/#https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@#')
fi
#参数【$2】代表下载目录,【$3】代表在线地址
#参数【$4】代表输出显示,【$5】不启用重定向
#参数【$6】代表验证证书,【$7】使用自定义UA
[ -n "$7" ] && agent="--user-agent \"$7\""
#参数【$1】代表下载目录,【$2】代表在线地址
#参数【$3】代表输出显示,【$4】不启用重定向
#参数【$5】代表验证证书,【$6】使用自定义UA
[ -n "$6" ] && agent="--user-agent \"$6\""
if wget --help 2>&1 | grep -q 'show-progress' >/dev/null 2>&1; then
[ "$4" = "echooff" ] && progress='-q' || progress='-q --show-progress'
[ "$5" = "rediroff" ] && redirect='--max-redirect=0' || redirect=''
[ "$6" = "skipceroff" ] && certificate='' || certificate='--no-check-certificate'
wget -Y on $agent $progress $redirect $certificate --timeout=3 -O "$2" "$url" && return 0 #成功则退出否则重试
wget -Y off $agent $progress $redirect $certificate --timeout=5 -O "$2" "$3"
[ "$3" = "echooff" ] && progress='-q' || progress='-q --show-progress'
[ "$4" = "rediroff" ] && redirect='--max-redirect=0' || redirect=''
[ "$5" = "skipceroff" ] && certificate='' || certificate='--no-check-certificate'
wget -Y on $agent $progress $redirect $certificate --timeout=3 -O "$1" "$url" && return 0 #成功则退出否则重试
wget -Y off $agent $progress $redirect $certificate --timeout=5 -O "$1" "$2"
return $?
elif curl --version >/dev/null 2>&1; then
[ "$4" = "echooff" ] && progress='-s' || progress='-#'
[ "$5" = "rediroff" ] && redirect='' || redirect='-L'
[ "$6" = "skipceroff" ] && certificate='' || certificate='-k'
[ "$3" = "echooff" ] && progress='-s' || progress='-#'
[ "$4" = "rediroff" ] && redirect='' || redirect='-L'
[ "$5" = "skipceroff" ] && certificate='' || certificate='-k'
if curl --version | grep -q '^curl 8.' && ckcmd base64; then
auth_b64=$(printf '%s' "$authentication" | base64)
result=$(curl $agent -w '%{http_code}' --connect-timeout 3 --proxy-header "Proxy-Authorization: Basic $auth_b64" $progress $redirect $certificate -o "$2" "$url")
result=$(curl $agent -w '%{http_code}' --connect-timeout 3 --proxy-header "Proxy-Authorization: Basic $auth_b64" $progress $redirect $certificate -o "$1" "$url")
else
result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$2" "$url")
result=$(curl $agent -w '%{http_code}' --connect-timeout 3 $progress $redirect $certificate -o "$1" "$url")
fi
[ "$result" = "200" ] && return 0 #成功则退出否则重试
export all_proxy=""
result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$2" "$3")
result=$(curl $agent -w '%{http_code}' --connect-timeout 5 $progress $redirect $certificate -o "$1" "$2")
[ "$result" = "200" ]
return $?
elif ckcmd wget;then
[ "$4" = "echooff" ] && progress='-q'
wget -Y on $progress -O "$2" "$url" && return 0 #成功则退出否则重试
wget -Y off $progress -O "$2" "$3"
[ "$3" = "echooff" ] && progress='-q'
wget -Y on $progress -O "$1" "$url" && return 0 #成功则退出否则重试
wget -Y off $progress -O "$1" "$2"
return $?
else
echo "找不到可用下载工具请安装Curl或Wget"

View File

@@ -0,0 +1,20 @@
#
put_save() { #推送面板选择
[ -z "$3" ] && request_type=PUT || request_type=$3
if curl --version >/dev/null 2>&1; then
curl -sS -X "$request_type" -H "Authorization: Bearer $secret" -H "Content-Type:application/json" "$1" -d "$2" >/dev/null
elif wget --version >/dev/null 2>&1; then
wget -q --method="$request_type" --header="Authorization: Bearer $secret" --header="Content-Type:application/json" --body-data="$2" "$1" >/dev/null
fi
}
web_restore() { #还原面板选择
num=$(cat "$CRASHDIR"/configs/web_save | wc -l)
i=1
while [ "$i" -le "$num" ]; do
group_name=$(awk -F ',' 'NR=="'${i}'" {print $1}' "$CRASHDIR"/configs/web_save | sed 's/ /%20/g')
now_name=$(awk -F ',' 'NR=="'${i}'" {print $2}' "$CRASHDIR"/configs/web_save)
put_save "http://127.0.0.1:${db_port}/proxies/${group_name}" "{\"name\":\"${now_name}\"}"
i=$((i + 1))
done
}

30
scripts/libs/web_save.sh Normal file
View File

@@ -0,0 +1,30 @@
#
get_save() { #获取面板信息
if curl --version >/dev/null 2>&1; then
curl -s -H "Authorization: Bearer ${secret}" -H "Content-Type:application/json" "$1"
elif [ -n "$(wget --help 2>&1 | grep '\-\-method')" ]; then
wget -q --header="Authorization: Bearer ${secret}" --header="Content-Type:application/json" -O - "$1"
fi
}
web_save() { #最小化保存面板节点选择
#使用get_save获取面板节点设置
get_save "http://127.0.0.1:${db_port}/proxies" | sed 's/{}//g' | sed 's/:{/\
/g'| grep -aE '"Selector"' >"$TMPDIR"/web_proxies
[ -s "$TMPDIR"/web_proxies ] && while read line; do
def=$(echo $line | grep -oE '"all".*",' | awk -F "[\"]" '{print $4}')
now=$(echo $line | grep -oE '"now".*",' | awk -F "[\"]" '{print $4}')
[ "$def" != "$now" ] && {
name=$(echo $line | grep -oE '"name".*",' | awk -F "[\"]" '{print $4}')
echo "${name},${now}" >>"$TMPDIR"/web_save
}
done <"$TMPDIR"/web_proxies
rm -rf "$TMPDIR"/web_proxies
#对比文件,如果有变动且不为空则写入磁盘,否则清除缓存
for file in web_save web_configs; do
if [ -s "$TMPDIR"/${file} ]; then
. "$CRASHDIR"/libs/compare.sh && compare "$TMPDIR"/${file} "$CRASHDIR"/configs/${file}
[ "$?" = 0 ] && rm -rf "$TMPDIR"/${file} || mv -f "$TMPDIR"/${file} "$CRASHDIR"/configs/${file}
fi
done
}

View File

@@ -7,14 +7,14 @@ CRASHDIR=$(
)
CFG_PATH="$CRASHDIR"/configs/ShellCrash.cfg
#加载执行目录,失败则初始化
. "$CRASHDIR"/configs/command.env 2>/dev/null
. "$CRASHDIR"/libs/get_config.sh
[ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1
[ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR"
[ -n "$(tar --help 2>&1 | grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容
#通用工具
. "$CRASHDIR"/libs/set_config.sh
. "$CRASHDIR"/libs/check_cmd.sh
. "$CRASHDIR"/menus/1_start.sh
errornum() {
echo "-----------------------------------------------"
echo -e "\033[31m请输入正确的字母或数字\033[0m"
@@ -51,12 +51,6 @@ ckstatus() { #脚本启动前检查
fi
versionsh=$(cat "$CRASHDIR"/version)
[ -n "$versionsh" ] && versionsh_l=$versionsh
#服务器缺省地址
[ -z "$mix_port" ] && mix_port=7890
[ -z "$redir_port" ] && redir_port=7892
[ -z "$fwmark" ] && fwmark=$redir_port
[ -z "$db_port" ] && db_port=9999
[ -z "$dns_port" ] && dns_port=1053
[ -z "$redir_mod" ] && redir_mod=纯净模式
#获取本机host地址
[ -z "$host" ] && host=$(ubus call network.interface.lan status 2>&1 | grep \"address\" | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
@@ -132,29 +126,22 @@ ckstatus() { #脚本启动前检查
#检查执行权限
[ ! -x "$CRASHDIR"/start.sh ] && chmod +x "$CRASHDIR"/start.sh
#检查/tmp内核文件
for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(gz|zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do
chmod +x /tmp/$file
for file in $(ls /tmp | grep -v [/$] | grep -v ' ' | grep -Ev ".*(zip|7z|tar)$" | grep -iE 'CrashCore|^clash$|^clash-linux.*|^mihomo.*|^sing.*box|meta.*'); do
echo -e "发现可用的内核文件: \033[36m/tmp/$file\033[0m "
read -p "是否加载(会停止当前服务)(1/0) > " res
[ "$res" = 1 ] && {
"$CRASHDIR"/start.sh stop
core_v=$(/tmp/$file -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //')
[ -z "$core_v" ] && core_v=$(/tmp/$file version 2>/dev/null | grep -Eo 'version .*' | sed 's/version //')
if [ -n "$core_v" ]; then
. "$CRASHDIR"/menus/9_upgrade.sh && setcoretype &&
mv -f /tmp/$file "$TMPDIR"/CrashCore &&
tar -zcf "$BINDIR"/CrashCore.tar.gz ${tar_para} -C "$TMPDIR" CrashCore &&
echo -e "\033[32m内核加载完成\033[0m " &&
setconfig crashcore $crashcore &&
setconfig core_v $core_v &&
switch_core
sleep 1
zip_type=$(echo "$file" | grep -oE 'tar.gz$|upx$|gz$')
. "$CRASHDIR"/menus/9_upgrade.sh && setcoretype
. "$CRASHDIR"/libs/core_tools.sh && core_check "/tmp/$file"
if [ "$?" = 0 ]; then
echo -e "\033[32m内核加载完成\033[0m "
switch_core
else
echo -e "\033[33m检测到不可用的内核文件可能是文件受损或CPU架构不匹配\033[0m"
rm -rf /tmp/$file
echo -e "\033[33m内核文件已移除请认真检查后重新上传\033[0m"
sleep 2
rm -rf /tmp/"$file"
echo -e "\033[33m内核文件已移除请认真检查后重新上传\033[0m"
fi
sleep 1
}
echo "-----------------------------------------------"
done
@@ -205,7 +192,7 @@ main_menu() {
exit
;;
1)
. "$CRASHDIR"/menus/1_start.sh && start_service
start_service
exit
;;
2)
@@ -279,7 +266,7 @@ case "$1" in
"$CRASHDIR"/start.sh $2 $3 $4 $5 $6
;;
-i)
. "$CRASHDIR"/init.sh
. "$CRASHDIR"/init.sh 2>/dev/null
;;
-st)
shtype=sh && [ -n "$(ls -l /bin/sh | grep -o dash)" ] && shtype=bash

View File

@@ -28,16 +28,7 @@ start_core() {
elif [ -s $core_config -o -n "$Url" -o -n "$Https" ]; then
"$CRASHDIR"/start.sh start
#设置循环检测以判定服务启动是否成功
i=1
while [ -z "$test" -a "$i" -lt 30 ]; do
sleep 1
if curl --version >/dev/null 2>&1; then
test=$(curl -s -H "Authorization: Bearer $secret" http://127.0.0.1:${db_port}/configs | grep -o port)
else
test=$(wget -q --header="Authorization: Bearer $secret" -O - http://127.0.0.1:${db_port}/configs | grep -o port)
fi
i=$((i + 1))
done
. "$CRASHDIR"/libs/start_wait.sh
[ -n "$test" -o -n "$(pidof CrashCore)" ] && startover
else
echo -e "\033[31m没有找到${crashcore}配置文件,请先导入配置文件!\033[0m"

View File

@@ -5,6 +5,7 @@ settings() { #功能设置
#获取设置默认显示
[ -z "$skip_cert" ] && skip_cert=已开启
[ -z "$sniffer" ] && sniffer=未启用
[ -z "$dns_mod" ] && dns_mod='redir_host'
#
echo "-----------------------------------------------"
echo -e "\033[30;47m欢迎使用功能设置菜单\033[0m"
@@ -38,7 +39,7 @@ settings() { #功能设置
settings
;;
2)
set_dns_mod
. "$CRASHDIR"/menus/dns.sh && set_dns_mod
sleep 1
settings
;;
@@ -278,69 +279,6 @@ set_redir_mod() { #代理模式设置
;;
esac
}
set_dns_mod() { #DNS模式设置
echo "-----------------------------------------------"
echo -e "当前DNS运行模式为\033[47;30m $dns_mod \033[0m"
echo -e "\033[33m切换模式后需要手动重启服务以生效\033[0m"
echo "-----------------------------------------------"
echo -e " 1 fake-ip模式 响应快,\033[33m兼容性较差\033[0m"
echo -e " 不支持CN-IP绕过功能"
echo -e " 2 redir_host模式\033[33m不安全易被污染\033[0m"
echo -e " 建议搭配第三方DNS服务使用"
if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then
echo -e " 3 mix混合模式 \033[32m防污染防泄露响应快推荐\033[0m"
echo -e " cn域名realip其他fakeip分流"
echo -e " 4 route模式 \033[32m防污染防泄露全真实IP\033[0m"
echo -e " cn域名realip其他dns2proxy分流"
fi
echo -e " 9 \033[36mDNS进阶设置\033[0m"
echo " 0 返回上级菜单"
read -p "请输入对应数字 > " num
case "$num" in
0) ;;
1)
dns_mod=fake-ip
setconfig dns_mod $dns_mod
echo "-----------------------------------------------"
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
;;
2)
dns_mod=redir_host
setconfig dns_mod $dns_mod
echo "-----------------------------------------------"
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
;;
3)
if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then
dns_mod=mix
setconfig dns_mod $dns_mod
echo "-----------------------------------------------"
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
else
echo -e "\033[31m当前内核不支持的功能\033[0m"
sleep 1
fi
;;
4)
if echo "$crashcore" | grep -q 'singbox' || [ "$crashcore" = meta ]; then
dns_mod=route
setconfig dns_mod $dns_mod
echo "-----------------------------------------------"
echo -e "\033[36m已设为 $dns_mod 模式!!\033[0m"
else
echo -e "\033[31m当前内核不支持的功能\033[0m"
sleep 1
fi
;;
9)
setdns
set_dns_mod
;;
*)
errornum
;;
esac
}
set_fw_filter(){ #流量过滤
[ -z "$common_ports" ] && common_ports=已开启
[ -z "$quic_rj" ] && quic_rj=未开启
@@ -830,7 +768,7 @@ set_adv_config() { #端口设置
set_firewall_area() { #代理范围设置
[ -z "$vm_redir" ] && vm_redir='未开启'
echo "-----------------------------------------------"
echo -e "\033[31m注意\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用6"
echo -e "\033[31m注意\033[0m基于桥接网卡的Docker/虚拟机流量,请单独启用!"
echo -e "\033[33m如你使用了第三方DNS如smartdns等请勿启用本机代理或使用shellcrash用户执行\033[0m"
echo "-----------------------------------------------"
echo -e " 1 \033[32m仅代理局域网流量\033[0m"

View File

@@ -1,196 +1,10 @@
#!/bin/ash
# Copyright (C) Juewuy
#加载全局变量
[ -z "$CRASHDIR" ] && CRASHDIR=$(cd "$(dirname "$(dirname "$0")")"; pwd)
[ -z "$BINDIR" ] && BINDIR=${CRASHDIR}
CFG_PATH=${CRASHDIR}/configs/ShellCrash.cfg
TMPDIR=/tmp/ShellCrash && [ ! -f ${TMPDIR} ] && mkdir -p ${TMPDIR}
. $CFG_PATH >/dev/null 2>&1
[ -n "$(tar --help 2>&1|grep -o 'no-same-owner')" ] && tar_para='--no-same-owner' #tar命令兼容
setconfig(){
#参数1代表变量名参数2代表变量值,参数3即文件路径
[ -z "$3" ] && configpath=$CFG_PATH || configpath=$3
[ -n "$(grep "\b${1}=" $configpath)" ] && sed -i "s#\b${1}=.*#${1}=${2}#g" $configpath || echo "${1}=${2}" >> $configpath
}
ckcmd(){ #检查命令是否存在
command -v sh >/dev/null 2>&1 && command -v $1 >/dev/null 2>&1 || type $1 >/dev/null 2>&1
}
#任务命令
check_update(){ #检查更新工具
${CRASHDIR}/start.sh get_bin ${TMPDIR}/crashversion "$1" echooff
[ "$?" = "0" ] && . ${TMPDIR}/crashversion 2>/dev/null
rm -rf ${TMPDIR}/crashversion
}
update_core(){ #自动更新内核
#检查版本
check_update bin/version
crash_v_new=$(eval echo \$${crashcore}_v)
if [ -z "$crash_v_new" -o "$crash_v_new" = "$core_v" ];then
logger "任务【自动更新内核】中止-未检测到版本更新"
exit 1
else
echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash
if [ -n "$custcorelink" ];then
zip_type=$(echo $custcorelink | grep -oE 'tar.gz$')
[ -z "$zip_type" ] && zip_type=$(echo $custcorelink | grep -oE 'gz$')
if [ -n "$zip_type" ];then
${CRASHDIR}/start.sh webget ${TMPDIR}/core_new.${zip_type} ${custcorelink}
fi
else
${CRASHDIR}/start.sh get_bin ${TMPDIR}/core_new.tar.gz bin/${crashcore}/${core_new}-linux-${cpucore}.tar.gz
fi
if [ "$?" != "0" ];then
logger "任务【自动更新内核】出错-下载失败!"
${TMPDIR}/CrashCore.tar.gz
return 1
else
[ -n "$(pidof CrashCore)" ] && ${CRASHDIR}/start.sh stop #停止内核服务防止内存不足
[ -f ${TMPDIR}/core_new.tar.gz ] && {
mkdir -p ${TMPDIR}/core_new_dir
[ "$BINDIR" = "$TMPDIR" ] && rm -rf ${TMPDIR}/CrashCore #小闪存模式防止空间不足
tar -zxf "${TMPDIR}/core_new.tar.gz" ${tar_para} -C ${TMPDIR}/core_new_dir/
for file in $(find ${TMPDIR}/core_new_dir 2>/dev/null);do
[ -f $file ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|premium)')" ] && mv -f $file ${TMPDIR}/core_new
done
rm -rf ${TMPDIR}/core_new_dir
}
[ -f ${TMPDIR}/core_new.gz ] && gunzip ${TMPDIR}/core_new.gz >/dev/null && rm -rf ${TMPDIR}/core_new.gz
chmod +x ${TMPDIR}/core_new
[ "$crashcore" = unknow ] && setcoretype
if echo "$crashcore" | grep -q 'singbox';then
core_v=$(${TMPDIR}/core_new version 2>/dev/null | grep version | awk '{print $3}')
else
core_v=$(${TMPDIR}/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //')
fi
if [ -z "$core_v" ];then
logger "任务【自动更新内核】出错-内核校验失败!"
rm -rf ${TMPDIR}/core_new.tar.gz
rm -rf ${TMPDIR}/core_new
${CRASHDIR}/start.sh start
return 1
else
mv -f ${TMPDIR}/core_new ${TMPDIR}/CrashCore
if [ -f ${TMPDIR}/core_new.tar.gz ];then
mv -f ${TMPDIR}/core_new.tar.gz ${BINDIR}/CrashCore.tar.gz
else
tar -zcf ${BINDIR}/CrashCore.tar.gz ${tar_para} -C ${TMPDIR} CrashCore
fi
logger "任务【自动更新内核】下载完成,正在重启服务!"
setconfig core_v $core_v
${CRASHDIR}/start.sh start
return 0
fi
fi
fi
}
update_scripts(){ #自动更新脚本
#检查版本
check_update version
if [ -z "$versionsh" -o "$versionsh" = "versionsh_l" ];then
logger "任务【自动更新脚本】中止-未检测到版本更新"
exit 1
else
${CRASHDIR}/start.sh get_bin ${TMPDIR}/clashfm.tar.gz "bin/update.tar.gz"
if [ "$?" != "0" ];then
rm -rf ${TMPDIR}/clashfm.tar.gz
logger "任务【自动更新内核】出错-下载失败!"
return 1
else
#停止服务
${CRASHDIR}/start.sh stop
#解压
tar -zxf "${TMPDIR}/clashfm.tar.gz" ${tar_para} -C ${CRASHDIR}/
if [ $? -ne 0 ];then
rm -rf ${TMPDIR}/clashfm.tar.gz
logger "任务【自动更新内核】出错-解压失败!"
${CRASHDIR}/start.sh start
return 1
else
. ${CRASHDIR}/init.sh >/dev/null
${CRASHDIR}/start.sh start
return 0
fi
fi
fi
}
update_mmdb(){ #自动更新数据库
getgeo(){
#检查版本
check_update bin/version
geo_v="$(echo $2 | awk -F "." '{print $1}')_v" #获取版本号类型比如Country_v
geo_v_new=$GeoIP_v
geo_v_now=$(eval echo \$$geo_v)
if [ -z "$geo_v_new" -o "$geo_v_new" = "$geo_v_now" ];then
logger "任务【自动更新数据库文件】跳过-未检测到$2版本更新"
else
#更新文件
${CRASHDIR}/start.sh get_bin ${TMPDIR}/$1 "bin/geodata/$2"
if [ "$?" != "0" ];then
logger "任务【自动更新数据库文件】更新【$2】下载失败!"
rm -rf ${TMPDIR}/$1
else
mv -f ${TMPDIR}/$1 ${BINDIR}/$1
setconfig $geo_v $GeoIP_v
logger "任务【自动更新数据库文件】更新【$2】成功!"
fi
fi
}
[ -n "${cn_mini_v}" -a -s $CRASHDIR/Country.mmdb ] && getgeo Country.mmdb cn_mini.mmdb
[ -n "${china_ip_list_v}" -a -s $CRASHDIR/cn_ip.txt ] && getgeo cn_ip.txt china_ip_list.txt
[ -n "${china_ipv6_list_v}" -a -s $CRASHDIR/cn_ipv6.txt ] && getgeo cn_ipv6.txt china_ipv6_list.txt
[ -n "${geosite_v}" -a -s $CRASHDIR/GeoSite.dat ] && getgeo GeoSite.dat geosite.dat
[ -n "${geoip_cn_v}" -a -s $CRASHDIR/geoip.db ] && getgeo geoip.db geoip_cn.db
[ -n "${geosite_cn_v}" -a -s $CRASHDIR/geosite.db ] && getgeo geosite.db geosite_cn.db
[ -n "${mrs_geosite_cn_v}" -a -s $CRASHDIR/geosite-cn.mrs ] && getgeo geosite-cn.mrs mrs_geosite_cn.mrs
[ -n "${srs_geoip_cn_v}" -a -s $CRASHDIR/geoip-cn.srs ] && getgeo geoip-cn.srs srs_geoip_cn.srs
[ -n "${srs_geosite_cn_v}" -a -s $CRASHDIR/geosite-cn.srs ] && getgeo geosite-cn.srs srs_geosite_cn.srs
return 0
}
reset_firewall(){ #重设透明路由防火墙
${CRASHDIR}/start.sh stop_firewall
${CRASHDIR}/start.sh afstart
}
ntp(){
[ "$crashcore" != singbox ] && ckcmd ntpd && ntpd -n -q -p 203.107.6.88 >/dev/null 2>&1 || exit 0 &
}
#通用工具
. "$CRASHDIR"/libs/set_config.sh
. "$CRASHDIR"/libs/set_cron.sh
#任务工具
logger(){
[ "$task_push" = 1 ] && push= || push=off
[ -n "$2" -a "$2" != 0 ] && echo -e "\033[$2m$1\033[0m"
[ "$3" = 'off' ] && push=off
echo "$1" |grep -qE '(每隔|时每)([1-9]|[1-9][0-9])分钟' && push=off
${CRASHDIR}/start.sh logger "$1" 0 "$push"
}
croncmd(){
if [ -n "$(crontab -h 2>&1 | grep '\-l')" ];then
crontab $1
else
crondir="$(crond -h 2>&1 | grep -oE 'Default:.*' | awk -F ":" '{print $2}')"
[ ! -w "$crondir" ] && crondir="/etc/storage/cron/crontabs"
[ ! -w "$crondir" ] && crondir="/var/spool/cron/crontabs"
[ ! -w "$crondir" ] && crondir="/var/spool/cron"
if [ -w "$crondir" ];then
[ "$1" = "-l" ] && cat $crondir/$USER 2>/dev/null
[ -f "$1" ] && cat $1 > $crondir/$USER
else
echo "你的设备不支持定时任务配置,脚本大量功能无法启用,请尝试使用搜索引擎查找安装方式!"
fi
fi
}
cronset(){
# 参数1代表要移除的关键字,参数2代表要添加的任务语句
tmpcron=${TMPDIR}/cron_$USER
croncmd -l > $tmpcron 2>/dev/null
sed -i "/$1/d" $tmpcron
sed -i '/^$/d' $tmpcron
echo "$2" >> $tmpcron
croncmd $tmpcron
#华硕/Padavan固件存档在本地,其他则删除
[ -d /jffs -o -d /etc/storage/clash -o -d /etc/storage/ShellCrash ] && mv -f $tmpcron ${CRASHDIR}/task/cron || rm -f $tmpcron
}
set_cron(){
[ -z $week ] && week=*
[ -z $hour ] && hour=*
@@ -208,7 +22,7 @@ set_cron(){
}
set_service(){
# 参数1代表要任务类型,参数2代表任务ID,参数3代表任务描述,参数4代表running任务cron时间
task_file=${CRASHDIR}/task/$1
task_file="$CRASHDIR"/task/$1
[ -s $task_file ] && sed -i "/$3/d" $task_file
#运行时每分钟执行的任务特殊处理
if [ "$1" = "running" ];then
@@ -232,12 +46,12 @@ task_user_add(){ #自定义命令添加
task_command=$script
echo -e "请检查输入:\033[32m$task_command\033[0m"
#获取本任务ID
task_max_id=$(awk -F '#' '{print $1}' ${CRASHDIR}/task/task.user 2>/dev/null | sort -n | tail -n 1)
task_max_id=$(awk -F '#' '{print $1}' "$CRASHDIR"/task/task.user 2>/dev/null | sort -n | tail -n 1)
[ -z "$task_max_id" ] && task_max_id=200
task_id=$((task_max_id + 1))
read -p "请输入任务备注 > " txt
[ -n "$txt" ] && task_name=$txt || task_name=自定义任务$task_id
echo "$task_id#$task_command#$task_name" >> ${CRASHDIR}/task/task.user
echo "$task_id#$task_command#$task_name" >> "$CRASHDIR"/task/task.user
echo -e "\033[32m自定义任务已添加\033[0m"
sleep 1
else
@@ -250,13 +64,13 @@ task_user_del(){ #自定义命令删除
echo -e "请输入对应ID移除对应自定义任务(不会影响内置任务)"
echo -e "也可以手动编辑\033[32m${CRASHDIR}/task/task.user\033[0m"
echo "-----------------------------------------------"
cat ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^#' | awk -F '#' '{print $1" "$3}'
cat "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^#' | awk -F '#' '{print $1" "$3}'
echo "-----------------------------------------------"
echo 0 返回上级菜单
echo "-----------------------------------------------"
read -p "请输入对应数字 > " num
if [ -n "$num" ];then
sed -i "/^$num#/d" ${CRASHDIR}/task/task.user 2>/dev/null
sed -i "/^$num#/d" "$CRASHDIR"/task/task.user 2>/dev/null
[ "$num" != 0 ] && task_user_del
else
echo -e "\033[31m输入错误请重新输入\033[0m"
@@ -268,7 +82,7 @@ task_add(){ #任务添加
echo -e "\033[36m请选择需要添加的任务\033[0m"
echo "-----------------------------------------------"
#输出任务列表
cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | awk -F '#' '{print " "NR" "$3}'
cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | awk -F '#' '{print " "NR" "$3}'
echo "-----------------------------------------------"
echo -e " 0 返回上级菜单"
read -p "请输入对应数字 > " num
@@ -276,9 +90,9 @@ task_add(){ #任务添加
0)
;;
[1-9]|[1-9][0-9])
if [ "$num" -le "$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | wc -l)" ];then
task_id=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $1}')
task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $3}')
if [ "$num" -le "$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | wc -l)" ];then
task_id=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $1}')
task_name=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep -Ev '^(#|$)' | sed -n "$num p" | awk -F '#' '{print $3}')
task_type
else
errornum
@@ -291,14 +105,14 @@ task_add(){ #任务添加
}
task_del(){ #任务删除
#删除定时任务
croncmd -l > ${TMPDIR}/cron && sed -i "/$1/d" ${TMPDIR}/cron && croncmd ${TMPDIR}/cron
rm -f ${TMPDIR}/cron
croncmd -l > "$TMPDIR"/cron && sed -i "/$1/d" "$TMPDIR"/cron && croncmd "$TMPDIR"/cron
rm -f "$TMPDIR"/cron
#删除条件任务
sed -i "/$1/d" ${CRASHDIR}/task/cron 2>/dev/null
sed -i "/$1/d" ${CRASHDIR}/task/bfstart 2>/dev/null
sed -i "/$1/d" ${CRASHDIR}/task/afstart 2>/dev/null
sed -i "/$1/d" ${CRASHDIR}/task/running 2>/dev/null
sed -i "/$1/d" ${CRASHDIR}/task/affirewall 2>/dev/null
sed -i "/$1/d" "$CRASHDIR"/task/cron 2>/dev/null
sed -i "/$1/d" "$CRASHDIR"/task/bfstart 2>/dev/null
sed -i "/$1/d" "$CRASHDIR"/task/afstart 2>/dev/null
sed -i "/$1/d" "$CRASHDIR"/task/running 2>/dev/null
sed -i "/$1/d" "$CRASHDIR"/task/affirewall 2>/dev/null
}
task_type(){ #任务条件选择菜单
echo "-----------------------------------------------"
@@ -393,20 +207,20 @@ task_type(){ #任务条件选择菜单
task_manager(){ #任务管理列表
echo "-----------------------------------------------"
#抽取并生成临时列表
croncmd -l > ${TMPDIR}/task_cronlist
cat ${TMPDIR}/task_cronlist ${CRASHDIR}/task/running 2>/dev/null | sort -u | grep -oE "task/task.sh .*" | awk -F ' ' '{print $2" "$3}' > ${TMPDIR}/task_list
cat ${CRASHDIR}/task/bfstart ${CRASHDIR}/task/afstart ${CRASHDIR}/task/affirewall 2>/dev/null | awk -F ' ' '{print $2" "$3}' >> ${TMPDIR}/task_list
cat ${TMPDIR}/task_cronlist 2>/dev/null | sort -u | grep -oE " #.*" | grep -v "守护" | awk -F '#' '{print "0 旧版任务-"$2}' >> ${TMPDIR}/task_list
sed -i '/^ *$/d' ${TMPDIR}/task_list
rm -rf ${TMPDIR}/task_cronlist
croncmd -l > "$TMPDIR"/task_cronlist
cat "$TMPDIR"/task_cronlist "$CRASHDIR"/task/running 2>/dev/null | sort -u | grep -oE "task/task.sh .*" | awk -F ' ' '{print $2" "$3}' > "$TMPDIR"/task_list
cat "$CRASHDIR"/task/bfstart "$CRASHDIR"/task/afstart "$CRASHDIR"/task/affirewall 2>/dev/null | awk -F ' ' '{print $2" "$3}' >> "$TMPDIR"/task_list
cat "$TMPDIR"/task_cronlist 2>/dev/null | sort -u | grep -oE " #.*" | grep -v "守护" | awk -F '#' '{print "0 旧版任务-"$2}' >> "$TMPDIR"/task_list
sed -i '/^ *$/d' "$TMPDIR"/task_list
rm -rf "$TMPDIR"/task_cronlist
#判断为空则返回
if [ ! -s ${TMPDIR}/task_list ];then
if [ ! -s "$TMPDIR"/task_list ];then
echo -e "\033[31m当前没有可供管理的任务\033[36m"
sleep 1
else
echo -e "\033[33m已添加的任务:\033[0m"
echo "-----------------------------------------------"
cat ${TMPDIR}/task_list | awk '{print " " NR " " $2}'
cat "$TMPDIR"/task_list | awk '{print " " NR " " $2}'
echo "-----------------------------------------------"
echo -e " a 清空旧版任务"
echo -e " d 清空任务列表"
@@ -427,7 +241,7 @@ task_manager(){ #任务管理列表
;;
[1-9]|[1-9][0-9])
task_txt=$(sed -n "$num p" ${TMPDIR}/task_list)
task_txt=$(sed -n "$num p" "$TMPDIR"/task_list)
task_id=$(echo $task_txt | awk '{print $1}')
if [ "$task_id" = 0 ];then
read -p "旧版任务不支持管理,是否移除?(1/0) > " res
@@ -439,7 +253,7 @@ task_manager(){ #任务管理列表
}
else
task_des=$(echo $task_txt | awk '{print $2}')
task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $3}')
task_name=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $3}')
echo "-----------------------------------------------"
echo -e "当前任务为:\033[36m $task_des\033[0m"
echo -e " 1 \033[33m修改\033[0m当前任务"
@@ -459,15 +273,15 @@ task_manager(){ #任务管理列表
task_del $task_des
;;
3)
task_command=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $2}')
task_command=$(cat "$CRASHDIR"/task/task.list "$CRASHDIR"/task/task.user 2>/dev/null | grep "$task_id" | awk -F '#' '{print $2}')
eval $task_command && task_res='执行成功!' || task_res='执行失败!'
logger "任务【$task_des$task_res" 33 off
echo -e "\033[33m任务【$task_des$task_res\033[0m"
sleep 1
;;
4)
echo "-----------------------------------------------"
if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep "$task_name")" ];then
cat ${TMPDIR}/ShellCrash.log | grep "$task_name"
if [ -n "$(cat "$TMPDIR"/ShellCrash.log | grep "$task_name")" ];then
cat "$TMPDIR"/ShellCrash.log | grep "$task_name"
else
echo -e "\033[31m未找到相关执行记录\033[0m"
fi
@@ -504,7 +318,7 @@ task_recom(){ #任务推荐
}
task_menu(){ #任务菜单
#检测并创建自定义任务文件
[ -f ${CRASHDIR}/task/task.user ] || echo '#任务ID(必须>200并顺序排列)#任务命令#任务说明(#号隔开,任务命令和说明中都不允许包含#号)' > ${CRASHDIR}/task/task.user
[ -f "$CRASHDIR"/task/task.user ] || echo '#任务ID(必须>200并顺序排列)#任务命令#任务说明(#号隔开,任务命令和说明中都不允许包含#号)' > "$CRASHDIR"/task/task.user
echo "-----------------------------------------------"
echo -e "\033[30;47m欢迎使用自动任务功能\033[0m"
echo "-----------------------------------------------"
@@ -527,13 +341,13 @@ task_menu(){ #任务菜单
;;
2)
task_manager
rm -rf ${TMPDIR}/task_list
rm -rf "$TMPDIR"/task_list
task_menu
;;
3)
if [ -n "$(cat ${TMPDIR}/ShellCrash.log | grep '任务【')" ];then
if [ -n "$(cat "$TMPDIR"/ShellCrash.log | grep '任务【')" ];then
echo "-----------------------------------------------"
cat ${TMPDIR}/ShellCrash.log | grep '任务【'
cat "$TMPDIR"/ShellCrash.log | grep '任务【'
else
echo -e "\033[31m未找到任务相关执行日志\033[0m"
fi
@@ -543,7 +357,7 @@ task_menu(){ #任务菜单
4)
echo "-----------------------------------------------"
echo -e "\033[36m请在日志工具中配置相关推送通道及推送开关\033[0m"
log_pusher
. "$CRASHDIR"/menus/8_tools.sh && log_pusher
task_menu
;;
5)
@@ -563,21 +377,4 @@ task_menu(){ #任务菜单
;;
esac
}
case "$1" in
menu)
task_menu
;;
[1-9][0-9][0-9])
task_command=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$1" | awk -F '#' '{print $2}')
task_name=$(cat ${CRASHDIR}/task/task.list ${CRASHDIR}/task/task.user 2>/dev/null | grep "$1" | awk -F '#' '{print $3}')
#logger "任务$task_name 开始执行"
eval $task_command && task_res=成功 || task_res=失败
logger "任务【$2】执行$task_res"
;;
*)
$1
;;
esac

View File

@@ -412,7 +412,7 @@ EOF
cut -c 1- ${TMPDIR}/providers/providers.yaml ${TMPDIR}/providers/proxy-groups.yaml ${TMPDIR}/providers/rules.yaml > ${TMPDIR}/config.yaml
rm -rf ${TMPDIR}/providers
#调用内核测试
${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml
. "$CRASHDIR"/libs/core_webget.sh && core_find && ${TMPDIR}/CrashCore -t -d ${BINDIR} -f ${TMPDIR}/config.yaml
if [ "$?" = 0 ];then
echo -e "\033[32m配置文件生成成功\033[0m"
mkdir -p ${CRASHDIR}/yamls
@@ -514,7 +514,7 @@ EOF
cat ${TMPDIR}/provider_temp_file | sed "s/{providers_tags}/$providers_tags/g" > ${TMPDIR}/providers/outbounds.json
rm -rf ${TMPDIR}/provider_temp_file
#调用内核测试
${CRASHDIR}/start.sh core_check && ${TMPDIR}/CrashCore merge ${TMPDIR}/config.json -C ${TMPDIR}/providers
. "$CRASHDIR"/libs/core_webget.sh && core_find && ${TMPDIR}/CrashCore merge ${TMPDIR}/config.json -C ${TMPDIR}/providers
if [ "$?" = 0 ];then
echo -e "\033[32m配置文件生成成功如果启动超时建议更新里手动安装Singbox-srs数据库常用包\033[0m"
mkdir -p ${CRASHDIR}/jsons
@@ -895,8 +895,8 @@ gen_link_ele(){ #在线生成节点筛选
fi
setconfig include "'$include'"
}
get_core_config(){ #调用工具下载
${CRASHDIR}/start.sh get_core_config
jump_core_config(){ #调用工具下载
. "$CRASHDIR"/starts/core_config.sh && get_core_config
if [ "$?" = 0 ];then
if [ "$inuserguide" != 1 ];then
read -p "是否启动服务以使配置文件生效?(1/0) > " res
@@ -949,7 +949,7 @@ gen_core_config_link(){ #在线生成工具
setconfig Https
setconfig Url "'$Url_link'"
#获取在线yaml文件
get_core_config
jump_core_config
else
echo "-----------------------------------------------"
echo -e "\033[31m请先输入订阅或分享链接\033[0m"
@@ -1004,7 +1004,7 @@ set_core_config_link(){ #直接导入配置
setconfig Https "'$link'"
setconfig Url
#获取在线yaml文件
get_core_config
jump_core_config
else
set_core_config_link
fi
@@ -1117,7 +1117,7 @@ set_core_config(){ #配置文件功能
echo "-----------------------------------------------"
read -p "确认更新配置文件?[1/0] > " res
if [ "$res" = '1' ]; then
get_core_config
jump_core_config
else
set_core_config
fi

View File

@@ -276,7 +276,7 @@ log_pusher() {
chat=$(wget -Y on -q -O - $url_tg)
fi
[ -n "$chat" ] && chat_ID=$(echo $chat | sed 's/"update_id":/{\n"update_id":/g' | grep "$public_key" | head -n1 | grep -oE '"id":.*,"is_bot' | sed s'/"id"://' | sed s'/,"is_bot//')
[ -z "$chat_ID" ] && {
[ -z "$chat_ID" ] && [ "$TOKEN" != 'publictoken' ] && {
echo -e "\033[31m无法获取对话ID请返回重新设置或手动输入ChatID\033[0m"
echo -e "通常访问 \033[32;4m$url_tg\033[0m \n\033[36m即可看到ChatID\033[0m"
read -p "请手动输入ChatID > " chat_ID
@@ -695,8 +695,8 @@ debug(){
main_menu
;;
9)
"$CRASHDIR"/start.sh core_check && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && echo -e "\033[32m合并成功\033[0m"
rm -rf "$TMPDIR"/CrashCore
. "$CRASHDIR"/libs/core_webget.sh && core_find && "$TMPDIR"/CrashCore merge "$TMPDIR"/debug.json -C "$TMPDIR"/jsons && echo -e "\033[32m合并成功\033[0m"
[ "$TMPDIR" = "$BINDIR" ] && rm -rf "$TMPDIR"/CrashCore
main_menu
;;
*)

View File

@@ -2,6 +2,8 @@
# Copyright (C) Juewuy
. "$CRASHDIR"/libs/check_dir_avail.sh
. "$CRASHDIR"/libs/check_cpucore.sh
. "$CRASHDIR"/libs/web_get_bin.sh
error_down(){
echo -e "\033[33m请尝试切换至其他安装源后重新下载\033[0m"
@@ -103,10 +105,10 @@ upgrade(){
}
#检查更新
checkupdate(){
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/version_new version echooff
get_bin "$TMPDIR"/version_new version echooff
[ "$?" = "0" ] && {
version_new=$(cat "$TMPDIR"/version_new)
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/version_new bin/version echooff
get_bin "$TMPDIR"/version_new bin/version echooff
}
if [ "$?" = "0" ];then
. "$TMPDIR"/version_new 2>/dev/null
@@ -119,7 +121,7 @@ checkupdate(){
}
#更新脚本
getscripts(){
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz
get_bin "$TMPDIR"/ShellCrash.tar.gz ShellCrash.tar.gz
if [ "$?" != "0" ];then
echo -e "\033[33m文件下载失败\033[0m"
error_down
@@ -159,19 +161,6 @@ setscripts(){
fi
}
#更新内核
getcpucore(){ #自动获取内核架构
cputype=$(uname -ms | tr ' ' '_' | tr '[A-Z]' '[a-z]')
[ -n "$(echo $cputype | grep -E "linux.*armv.*")" ] && cpucore="armv5"
[ -n "$(echo $cputype | grep -E "linux.*armv7.*")" ] && [ -n "$(cat /proc/cpuinfo | grep vfp)" ] && [ ! -d /jffs ] && cpucore="armv7"
[ -n "$(echo $cputype | grep -E "linux.*aarch64.*|linux.*armv8.*")" ] && cpucore="arm64"
[ -n "$(echo $cputype | grep -E "linux.*86.*")" ] && cpucore="386"
[ -n "$(echo $cputype | grep -E "linux.*86_64.*")" ] && cpucore="amd64"
if [ -n "$(echo $cputype | grep -E "linux.*mips.*")" ];then
mipstype=$(echo -n I | hexdump -o 2>/dev/null | awk '{ print substr($2,6,1); exit}') #通过判断大小端判断mips或mipsle
[ "$mipstype" = "0" ] && cpucore="mips-softfloat" || cpucore="mipsle-softfloat"
fi
[ -n "$cpucore" ] && setconfig cpucore $cpucore
}
setcpucore(){ #手动设置内核架构
cpucore_list="armv5 armv7 arm64 386 amd64 mipsle-softfloat mipsle-hardfloat mips-softfloat"
echo "-----------------------------------------------"
@@ -234,85 +223,41 @@ switch_core(){ #clash与singbox内核切换
done
}
}
if echo "$crashcore" | grep -q 'singbox';then
COMMAND='"$TMPDIR/CrashCore run -D $BINDIR -C $TMPDIR/jsons"'
else
COMMAND='"$TMPDIR/CrashCore -d $BINDIR -f $TMPDIR/config.yaml"'
fi
setconfig COMMAND "$COMMAND" "$CRASHDIR"/configs/command.env && . "$CRASHDIR"/configs/command.env
}
getcore(){ #下载内核文件
. "$CRASHDIR"/libs/core_tools.sh #调用下载工具
[ -z "$crashcore" ] && crashcore=meta
[ -z "$cpucore" ] && getcpucore
[ -z "$cpucore" ] && check_cpucore
[ "$crashcore" = unknow ] && setcoretype
echo "$crashcore" | grep -q 'singbox' && core_new=singbox || core_new=clash
#获取在线内核文件
echo "-----------------------------------------------"
echo "正在在线获取$crashcore核心文件……"
if [ -n "$custcorelink" ];then
zip_type=$(echo $custcorelink | grep -oE 'tar.gz$')
[ -z "$zip_type" ] && zip_type=$(echo $custcorelink | grep -oE 'gz$')
if [ -n "$zip_type" ];then
"$CRASHDIR"/start.sh webget "$TMPDIR"/core_new.${zip_type} "$custcorelink"
else
echo -e "\033[31m链接不是以.tar.gz或.gz结尾下载已取消\033[0m"
exit
fi
else
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/core_new.tar.gz bin/${crashcore}/${core_new}-linux-${cpucore}.tar.gz
fi
if [ "$?" = "1" ];then
core_webget
case "$?" in
0)
echo -e "\033[32m$crashcore核心下载成功\033[0m"
sleep 1
switch_core
;;
1)
echo -e "\033[31m核心文件下载失败\033[0m"
rm -rf "$TMPDIR"/core_new.tar.gz
[ -z "$custcorelink" ] && error_down
else
[ -n "$(pidof CrashCore)" ] && {
"$CRASHDIR"/start.sh stop #停止内核服务防止内存不足
rm -rf "$TMPDIR"/CrashCore #删除缓存内核防止缓存空间不足
}
[ -f "$TMPDIR"/core_new.tar.gz ] && {
mkdir -p "$TMPDIR"/core_tmp
[ "$BINDIR" = "$TMPDIR" ] && rm -rf "$TMPDIR"/CrashCore #小闪存模式防止空间不足
tar -zxf ""$TMPDIR"/core_new.tar.gz" ${tar_para} -C "$TMPDIR"/core_tmp/
for file in $(find "$TMPDIR"/core_tmp 2>/dev/null);do
[ -f $file ] && [ -n "$(echo $file | sed 's#.*/##' | grep -iE '(CrashCore|sing|meta|mihomo|clash|premium)')" ] && mv -f $file "$TMPDIR"/core_new
done
rm -rf "$TMPDIR"/core_tmp
}
[ -f "$TMPDIR"/core_new.gz ] && gunzip "$TMPDIR"/core_new.gz && rm -rf "$TMPDIR"/core_new.gz
chmod +x "$TMPDIR"/core_new
[ "$crashcore" = unknow ] && setcoretype
if echo "$crashcore" | grep -q 'singbox';then
core_v=$("$TMPDIR"/core_new version 2>/dev/null | grep version | awk '{print $3}')
else
core_v=$("$TMPDIR"/core_new -v 2>/dev/null | head -n 1 | sed 's/ linux.*//;s/.* //')
fi
if [ -z "$core_v" ];then
echo -e "\033[31m核心文件下载成功但校验失败请尝试手动指定CPU版本\033[0m"
rm -rf "$TMPDIR"/core_new
rm -rf "$TMPDIR"/core_new.tar.gz
setcpucore
else
echo -e "\033[32m$crashcore核心下载成功\033[0m"
sleep 1
mv -f "$TMPDIR"/core_new "$TMPDIR"/CrashCore
if [ -f "$TMPDIR"/core_new.tar.gz ];then
mv -f "$TMPDIR"/core_new.tar.gz "$BINDIR"/CrashCore.tar.gz
else
tar -zcf "$BINDIR"/CrashCore.tar.gz ${tar_para} -C "$TMPDIR" CrashCore
fi
setconfig crashcore $crashcore
setconfig core_v $core_v
setconfig custcorelink $custcorelink
switch_core
fi
fi
;;
*)
echo -e "\033[31m核心文件下载成功但校验失败请尝试手动指定CPU版本\033[0m"
rm -rf ${TMPDIR}/core_new
rm -rf ${TMPDIR}/core_new.tar.gz
setcpucore
;;
esac
}
setcustcore(){ #自定义内核
checkcustcore(){
[ "$api_tag" = "latest" ] && api_url=latest || api_url="tags/$api_tag"
#通过githubapi获取内核信息
echo -e "\033[32m正在获取内核文件链接\033[0m"
"$CRASHDIR"/start.sh webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url}
webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url}
if [ "$?" = 0 ];then
release_tag=$(cat "$TMPDIR"/github_api | grep '"tag_name":' | awk -F '"' '{print $4}')
release_date=$(cat "$TMPDIR"/github_api | grep '"published_at":' | awk -F '"' '{print $4}')
@@ -358,7 +303,7 @@ setcustcore(){ #自定义内核
fi
rm -rf "$TMPDIR"/core.list
}
[ -z "$cpucore" ] && getcpucore
[ -z "$cpucore" ] && check_cpucore
echo "-----------------------------------------------"
echo -e "\033[36m此处内核通常源自互联网采集此处致谢各位开发者\033[0m"
echo -e "\033[33m自定义内核未经过完整适配使用出现问题请自行解决\033[0m"
@@ -426,7 +371,7 @@ setcustcore(){ #自定义内核
a)
read -p "请输入自定义内核的链接地址(必须是以.tar.gz或.gz结尾的压缩文件) > " link
[ -n "$link" ] && custcorelink="$link"
crashcore=unknow
setcoretype
getcore
;;
*)
@@ -437,12 +382,11 @@ setcustcore(){ #自定义内核
setcore(){ #内核选择菜单
#获取核心及版本信息
[ -z "$crashcore" ] && crashcore="unknow"
[ ! -f "$CRASHDIR"/CrashCore.tar.gz -o ! -f "$BINDIR"/CrashCore.tar.gz ] && crashcore="未安装核心"
echo "$crashcore" | grep -q 'singbox' && core_old=singbox || core_old=clash
[ -n "$custcorelink" ] && custcore="$(echo $custcorelink | sed 's#.*github.com##; s#/releases/download/#@#; s#-linux.*$##')"
###
echo "-----------------------------------------------"
[ -z "$cpucore" ] && getcpucore
[ -z "$cpucore" ] && check_cpucore
echo -e "当前内核:\033[42;30m $crashcore \033[47;30m$core_v\033[0m"
echo -e "当前系统处理器架构:\033[32m $cpucore \033[0m"
echo -e "\033[33m请选择需要使用的核心版本\033[0m"
@@ -515,7 +459,7 @@ getgeo(){ #下载Geo文件
#生成链接
echo "-----------------------------------------------"
echo 正在从服务器获取数据库文件…………
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype
get_bin "$TMPDIR"/${geoname} bin/geodata/$geotype
if [ "$?" = "1" ];then
echo "-----------------------------------------------"
echo -e "\033[31m文件下载失败\033[0m"
@@ -543,7 +487,7 @@ setcustgeo(){ #下载自定义数据库文件
getcustgeo(){
echo "-----------------------------------------------"
echo "正在获取数据库文件…………"
"$CRASHDIR"/start.sh webget "$TMPDIR"/$geoname $custgeolink
webget "$TMPDIR"/$geoname $custgeolink
if [ "$?" = "1" ];then
echo "-----------------------------------------------"
echo -e "\033[31m文件下载失败\033[0m"
@@ -563,7 +507,7 @@ setcustgeo(){ #下载自定义数据库文件
[ "$api_tag" = "latest" ] && api_url=latest || api_url="tags/$api_tag"
[ ! -s "$TMPDIR"/geo.list ] && {
echo -e "\033[32m正在查找可更新的数据库文件\033[0m"
"$CRASHDIR"/start.sh webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url}
webget "$TMPDIR"/github_api https://api.github.com/repos/${project}/releases/${api_url}
release_tag=$(cat "$TMPDIR"/github_api | grep '"tag_name":' | awk -F '"' '{print $4}')
cat "$TMPDIR"/github_api | grep "browser_download_url" | grep -oE 'releases/download.*' | grep -oiE 'geosite.*\.dat"$|country.*\.mmdb"$|.*.mrs|.*.srs' | sed 's|.*/||' | sed 's/"//' > "$TMPDIR"/geo.list
rm -rf "$TMPDIR"/github_api
@@ -755,7 +699,7 @@ getdb(){
dblink="${update_url}/"
echo "-----------------------------------------------"
echo 正在连接服务器获取安装文件…………
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz
get_bin "$TMPDIR"/clashdb.tar.gz bin/dashboard/${db_type}.tar.gz
if [ "$?" = "1" ];then
echo "-----------------------------------------------"
echo -e "\033[31m文件下载失败\033[0m"
@@ -896,7 +840,7 @@ setdb(){
getcrt(){
echo "-----------------------------------------------"
echo "正在连接服务器获取安装文件…………"
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt
get_bin "$TMPDIR"/ca-certificates.crt bin/fix/ca-certificates.crt
if [ "$?" = "1" ];then
echo "-----------------------------------------------"
echo -e "\033[31m文件下载失败\033[0m"
@@ -907,7 +851,7 @@ getcrt(){
[ -f $openssldir/certs ] && rm -rf $openssldir/certs #如果certs不是目录而是文件则删除并创建目录
mkdir -p $openssldir/certs
mv -f "$TMPDIR"/ca-certificates.crt $crtdir
"$CRASHDIR"/start.sh webget /dev/null https://baidu.com echooff rediron skipceroff
webget /dev/null https://baidu.com echooff rediron skipceroff
if [ "$?" = "1" ];then
export CURL_CA_BUNDLE=$crtdir
echo "export CURL_CA_BUNDLE=$crtdir" >> /etc/profile
@@ -1040,7 +984,7 @@ setserver(){
echo "-----------------------------------------------"
if [ -n "$url_id" ] && [ "$url_id" -lt 200 ];then
echo -ne "\033[32m正在获取版本信息\033[0m\r"
"$CRASHDIR"/start.sh get_bin "$TMPDIR"/release_version bin/release_version
get_bin "$TMPDIR"/release_version bin/release_version
if [ "$?" = "0" ];then
echo -e "\033[31m请选择想要回退至的稳定版版本\033[0m"
cat "$TMPDIR"/release_version | awk '{print " "NR" "$1}'

View File

@@ -16,6 +16,7 @@ set_dns_mod() { #DNS模式设置
echo -e " 4 route模式 \033[32m防污染防泄露全真实IP\033[0m"
echo -e " cn域名realip其他dns2proxy分流"
fi
echo "-----------------------------------------------"
[ "$dns_mod" = "fake-ip" ] || [ "$dns_mod" = "mix" ] &&
echo -e " 8 管理Fake-ip过滤列表"
echo -e " 9 \033[36mDNS进阶设置\033[0m"

View File

@@ -0,0 +1,149 @@
#!/bin/sh
# Copyright (C) Juewuy
. /tmp/SC_tmp/libs/check_dir_avail.sh
set_crashdir() {
set_usb_dir() {
echo -e "请选择安装目录"
du -hL /mnt | awk '{print " "NR" "$2" "$1}'
read -p "请输入相应数字 > " num
dir=$(du -hL /mnt | awk '{print $2}' | sed -n "$num"p)
if [ -z "$dir" ]; then
echo -e "\033[31m输入错误请重新设置\033[0m"
set_usb_dir
fi
}
set_asus_dir() {
echo -e "请选择U盘目录"
du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print " "NR" "$2" "$1}'
read -p "请输入相应数字 > " num
dir=$(du -hL /tmp/mnt | awk -F/ 'NF<=4' | awk '{print $2}' | sed -n "$num"p)
if [ ! -f "$dir/asusware.arm/etc/init.d/S50downloadmaster" ]; then
echo -e "\033[31m未找到下载大师自启文件$dir/asusware.arm/etc/init.d/S50downloadmaster请检查设置\033[0m"
set_asus_dir
fi
}
set_cust_dir() {
echo "-----------------------------------------------"
echo "可用路径 剩余空间:"
df -h | awk '{print $6,$4}' | sed 1d
echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!"
read -p "请输入自定义路径 > " dir
if [ "$(dir_avail $dir)" = 0 ] || [ -n "$(echo $dir | grep -E 'tmp|opt|sys')" ]; then
echo "\033[31m路径错误请重新设置\033[0m"
set_cust_dir
fi
}
echo "-----------------------------------------------"
if [ -n "$systype" ]; then
[ "$systype" = "Padavan" ] && dir=/etc/storage
[ "$systype" = "mi_snapshot" ] && {
echo -e "\033[33m检测到当前设备为小米官方系统请选择安装位置\033[0m"
[ -d /data ] && $echo " 1 安装到 /data 目录,剩余空间:$(dir_avail /data -h)(支持软固化功能)"
[ -d /userdisk ] && $echo " 2 安装到 /userdisk 目录,剩余空间:$(dir_avail /userdisk -h)(支持软固化功能)"
[ -d /data/other_vol ] && $echo " 3 安装到 /data/other_vol 目录,剩余空间:$(dir_avail /data/other_vol -h)(支持软固化功能)"
$echo " 4 安装到自定义目录(不推荐,不明勿用!)"
echo " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
case "$num" in
1)
dir=/data
;;
2)
dir=/userdisk
;;
3)
dir=/data/other_vol
;;
4)
set_cust_dir
;;
*)
exit 1
;;
esac
}
[ "$systype" = "asusrouter" ] && {
echo -e "\033[33m检测到当前设备为华硕固件请选择安装方式\033[0m"
echo -e " 1 基于USB设备安装(限23年9月之前固件须插入\033[31m任意\033[0mUSB设备)"
echo -e " 2 基于自启脚本安装(仅支持梅林及部分非koolshare官改固件)"
echo -e " 3 基于U盘+下载大师安装(支持所有固件限ARM设备须插入U盘或移动硬盘)"
echo -e " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
case "$num" in
1)
read -p "将脚本安装到USB存储/系统闪存?(1/0) > " res
[ "$res" = "1" ] && set_usb_dir || dir=/jffs
usb_status=1
;;
2)
echo -e "如无法正常开机启动请重新使用USB方式安装"
sleep 2
dir=/jffs
;;
3)
echo -e "请先在路由器网页后台安装下载大师并启用,之后选择外置存储所在目录!"
sleep 2
set_asus_dir
;;
*)
exit 1
;;
esac
}
[ "$systype" = "ng_snapshot" ] && dir=/tmp/mnt
else
echo -e "\033[33m安装ShellCrash至少需要预留约1MB的磁盘空间\033[0m"
echo -e " 1 在\033[32m/etc目录\033[0m下安装(适合root用户)"
echo -e " 2 在\033[32m/usr/share目录\033[0m下安装(适合Linux系统)"
echo -e " 3 在\033[32m当前用户目录\033[0m下安装(适合非root用户)"
echo -e " 4 在\033[32m外置存储\033[0m中安装"
echo -e " 5 手动设置安装目录"
echo -e " 0 退出安装"
echo "-----------------------------------------------"
read -p "请输入相应数字 > " num
#设置目录
case "$num" in
1)
dir=/etc
;;
2)
dir=/usr/share
;;
3)
dir=~/.local/share
mkdir -p ~/.config/systemd/user
;;
4)
set_usb_dir
;;
5)
echo "-----------------------------------------------"
echo "可用路径 剩余空间:"
df -h | awk '{print $6,$4}' | sed 1d
echo "路径是必须带 / 的格式,注意写入虚拟内存(/tmp,/opt,/sys...)的文件会在重启后消失!!!"
read -p "请输入自定义路径 > " dir
if [ -z "$dir" ]; then
echo -e "\033[31m路径错误请重新设置\033[0m"
setdir
fi
;;
*)
echo "安装已取消"
exit 1
;;
esac
fi
if [ ! -w $dir ]; then
echo -e "\033[31m没有$dir目录写入权限!请重新设置!\033[0m" && sleep 1 && setdir
else
echo -e "目标目录\033[32m$dir\033[0m空间剩余$(dir_avail $dir -h)"
read -p "确认安装?(1/0) > " res
[ "$res" = "1" ] && CRASHDIR=$dir/ShellCrash || setdir
fi
}

File diff suppressed because it is too large Load Diff

58
scripts/starts/afstart.sh Normal file
View File

@@ -0,0 +1,58 @@
#!/bin/ash
# Copyright (C) Juewuy
#初始化目录
[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd)
. "$CRASHDIR"/libs/get_config.sh
#加载工具
. "$CRASHDIR"/libs/check_cmd.sh
. "$CRASHDIR"/libs/logger.sh
. "$CRASHDIR"/libs/set_cron.sh
#缺省值
[ -z "$firewall_area" ] && firewall_area=1
#延迟启动
[ ! -f "$TMPDIR"/crash_start_time ] && [ -n "$start_delay" ] && [ "$start_delay" -gt 0 ] && {
logger "ShellCrash将延迟$start_delay秒启动" 31
sleep "$start_delay"
}
#设置循环检测面板端口以判定服务启动是否成功
. "$CRASHDIR"/libs/start_wait.sh
if [ -n "$test" -o -n "$(pidof CrashCore)" ]; then
[ "$start_old" = "已开启" ] && rm -rf "$TMPDIR"/CrashCore #删除缓存目录内核文件
. "$CRASHDIR"/starts/fw_start.sh #配置防火墙流量劫持
date +%s >"$TMPDIR"/crash_start_time #标记启动时间
#后台还原面板配置
[ -s "$CRASHDIR"/configs/web_save ] && {
. "$CRASHDIR"/libs/web_restore.sh
web_restore >/dev/null 2>&1 &
}
#推送日志
{
sleep 5
logger ShellCrash服务已启动
} &
ckcmd mtd_storage.sh && mtd_storage.sh save >/dev/null 2>&1 & #Padavan保存/etc/storage
#加载定时任务
[ -s "$CRASHDIR"/task/cron ] && croncmd "$CRASHDIR"/task/cron
[ -s "$CRASHDIR"/task/running ] && {
cronset '运行时每'
while read line; do
cronset '2fjdi124dd12s' "$line"
done <"$CRASHDIR"/task/running
}
[ "$start_old" = "已开启" ] && cronset '保守模式守护进程' "* * * * * test -z \"\$(pidof CrashCore)\" && $CRASHDIR/start.sh daemon #ShellCrash保守模式守护进程"
#加载条件任务
[ -s "$CRASHDIR"/task/afstart ] && { . "$CRASHDIR"/task/afstart; } &
[ -s "$CRASHDIR"/task/affirewall -a -s /etc/init.d/firewall -a ! -f /etc/init.d/firewall.bak ] && {
#注入防火墙
line=$(grep -En "fw.* restart" /etc/init.d/firewall | cut -d ":" -f 1)
sed -i.bak "${line}a\\. "$CRASHDIR"/task/affirewall" /etc/init.d/firewall
line=$(grep -En "fw.* start" /etc/init.d/firewall | cut -d ":" -f 1)
sed -i "${line}a\\. $CRASHDIR/task/affirewall" /etc/init.d/firewall
} &
#启动TG机器人
[ "$bot_tg_service" = ON ] && "$CRASHDIR"/menus/bot_tg.sh &
else
. "$CRASHDIR"/starts/start_error.sh
"$CRASHDIR"/start.sh stop
fi

136
scripts/starts/bfstart.sh Normal file
View File

@@ -0,0 +1,136 @@
#!/bin/ash
# Copyright (C) Juewuy
[ -z "$CRASHDIR" ] && CRASHDIR=$( cd $(dirname $0);cd ..;pwd)
. "$CRASHDIR"/libs/get_config.sh
[ -z "$BINDIR" -o -z "$TMPDIR" -o -z "$COMMAND" ] && . "$CRASHDIR"/init.sh >/dev/null 2>&1
[ ! -f "$TMPDIR" ] && mkdir -p "$TMPDIR"
#加载工具
. "$CRASHDIR"/libs/check_cmd.sh
. "$CRASHDIR"/libs/check_target.sh
. "$CRASHDIR"/libs/logger.sh
. "$CRASHDIR"/libs/web_get_bin.sh
. "$CRASHDIR"/libs/compare.sh
. "$CRASHDIR"/starts/check_geo.sh
. "$CRASHDIR"/starts/check_core.sh
#缺省值
[ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式'
[ -z "$dns_mod" ] && dns_mod='redir_host'
[ -z "$redir_mod" ] && firewall_area='4'
makehtml() { #生成面板跳转文件
cat >"$BINDIR"/ui/index.html <<EOF
<!DOCTYPE html>
<html lang="en">
<meta http-equiv="Cache-Control" content="no-cache, no-store, must-revalidate">
<meta http-equiv="Pragma" content="no-cache">
<meta http-equiv="Expires" content="0">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ShellCrash面板提示</title>
</head>
<body>
<div style="text-align: center; margin-top: 50px;">
<h1>您还未安装本地面板</h1>
<h3>请在脚本更新功能中(9-4)安装<br>或者使用在线面板:</h3>
<h4>请复制当前地址/ui(不包括)前面的内容填入url位置即可连接</h3>
<a href="http://board.zash.run.place" style="font-size: 24px;">Zashboard面板(推荐)<br></a>
<a style="font-size: 21px;"><br>如已安装请使用Ctrl+F5强制刷新此页面<br></a>
</div>
</body>
</html
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 <<EOF
function FindProxyForURL(url, host) {
if (
isInNet(host, "0.0.0.0", "255.0.0.0")||
isInNet(host, "10.0.0.0", "255.0.0.0")||
isInNet(host, "127.0.0.0", "255.0.0.0")||
isInNet(host, "224.0.0.0", "224.0.0.0")||
isInNet(host, "240.0.0.0", "240.0.0.0")||
isInNet(host, "172.16.0.0", "255.240.0.0")||
isInNet(host, "192.168.0.0", "255.255.0.0")||
isInNet(host, "169.254.0.0", "255.255.0.0")
)
return "DIRECT";
else
return "PROXY $host_pac:$mix_port; DIRECT; SOCKS5 $host_pac:$mix_port"
}
EOF
compare "$TMPDIR"/shellcrash_pac "$BINDIR"/ui/pac
[ "$?" = 0 ] && rm -rf "$TMPDIR"/shellcrash_pac || mv -f "$TMPDIR"/shellcrash_pac "$BINDIR"/ui/pac
}
routing_mark=$((fwmark + 2))
#检测网络连接
[ "$network_check" != "已禁用" ] && [ ! -f "$TMPDIR"/crash_start_time ] && ckcmd ping && . "$CRASHDIR"/starts/network_check && 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
. "$CRASHDIR"/starts/core_config.sh && 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
. "$CRASHDIR"/starts/singbox_check.sh && singbox_check
[ -d "$TMPDIR"/jsons ] && rm -rf "$TMPDIR"/jsons/* || mkdir -p "$TMPDIR"/jsons #准备目录
if [ "$disoverride" != "1" ];then
. "$CRASHDIR"/starts/singbox_modify.sh && modify_json
else
ln -sf "$core_config" "$TMPDIR"/config.json
fi
else
. "$CRASHDIR"/starts/clash_check.sh && clash_check
if [ "$disoverride" != "1" ];then
. "$CRASHDIR"/starts/clash_modify.sh && modify_yaml
else
ln -sf "$core_config" "$TMPDIR"/config.yaml
fi
fi
#检查下载cnip绕过相关文件
[ "$cn_ip_route" = "已开启" ] && [ "$dns_mod" != "fake-ip" ] && {
[ "$firewall_mod" = nftables ] || ckcmd ipset && {
. "$CRASHDIR"/starts/check_cnip.sh
ck_cn_ipv4
[ "$ipv6_redir" = "已开启" ] && ck_cn_ipv6
}
}
#添加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 /tmp/ShellCrash/debug.log
rm -rf "$CRASHDIR"/debug.log
return 0

View File

@@ -0,0 +1,24 @@
ck_cn_ipv4() { #CN-IP绕过
check_geo cn_ip.txt china_ip_list.txt
[ -f "$BINDIR"/cn_ip.txt ] && [ "$firewall_mod" = iptables ] && {
# see https://raw.githubusercontent.com/Hackl0us/GeoIP2-CN/release/CN-ip-cidr.txt
echo "create cn_ip hash:net family inet hashsize 10240 maxelem 10240" >"$TMPDIR"/cn_ip.ipset
awk '!/^$/&&!/^#/{printf("add cn_ip %s'" "'\n",$0)}' "$BINDIR"/cn_ip.txt >>"$TMPDIR"/cn_ip.ipset
ipset destroy cn_ip >/dev/null 2>&1
ipset -! restore <"$TMPDIR"/cn_ip.ipset
rm -rf "$TMPDIR"/cn_ip.ipset
}
}
ck_cn_ipv6() { #CN-IPV6绕过
check_geo cn_ipv6.txt china_ipv6_list.txt
[ -f "$BINDIR"/cn_ipv6.txt ] && [ "$firewall_mod" = iptables ] && {
#ipv6
#see https://ispip.clang.cn/all_cn_ipv6.txt
echo "create cn_ip6 hash:net family inet6 hashsize 5120 maxelem 5120" >"$TMPDIR"/cn_ipv6.ipset
awk '!/^$/&&!/^#/{printf("add cn_ip6 %s'" "'\n",$0)}' "$BINDIR"/cn_ipv6.txt >>"$TMPDIR"/cn_ipv6.ipset
ipset destroy cn_ip6 >/dev/null 2>&1
ipset -! restore <"$TMPDIR"/cn_ipv6.ipset
rm -rf "$TMPDIR"/cn_ipv6.ipset
}
}

View File

@@ -0,0 +1,18 @@
. "$CRASHDIR"/libs/check_target.sh
. "$CRASHDIR"/libs/core_tools.sh
. "$CRASHDIR"/configs/command.env
check_core() { #检查及下载内核文件
[ -n "$(find --help 2>&1 | grep -o size)" ] && find_para=' -size +2000' #find命令兼容
[ -z "$(find "$TMPDIR"/CrashCore $find_para 2>/dev/null)" ] && core_find
[ -z "$(find "$TMPDIR"/CrashCore 2>/dev/null)" ] && {
logger "未找到【$crashcore】核心,正在下载!" 33
[ -z "$cpucore" ] && . "$CRASHDIR"/libs/check_cpucore.sh && check_cpucore
[ -z "$cpucore" ] && logger 找不到设备的CPU信息请手动指定处理器架构类型 31 && exit 1
core_webget || logger "核心下载失败,请重新运行或更换安装源!" 31
}
[ ! -x "$TMPDIR"/CrashCore ] && chmod +x "$TMPDIR"/CrashCore 2>/dev/null #自动授权
[ "$start_old" != "已开启" -a "$(cat /proc/1/comm)" = "systemd" ] && restorecon -RF "$CRASHDIR" 2>/dev/null #修复SELinux权限问题
return 0
}

View File

@@ -0,0 +1,16 @@
check_geo() { #查找及下载Geo数据文件
[ ! -d "$BINDIR"/ruleset ] && mkdir -p "$BINDIR"/ruleset
find --help 2>&1 | grep -q size && find_para=' -size +20' #find命令兼容
[ -z "$(find "$BINDIR"/"$1" "$find_para" 2>/dev/null)" ] && {
if [ -n "$(find "$CRASHDIR"/"$1" "$find_para" 2>/dev/null)" ]; then
mv "$CRASHDIR"/"$1" "$BINDIR"/"$1" #小闪存模式移动文件
else
logger "未找到${1}文件,正在下载!" 33
get_bin "$BINDIR"/"$1" bin/geodata/"$2"
[ "$?" = "1" ] && rm -rf "${BINDIR}"/"${1}" && logger "${1}文件下载失败,已退出!请前往更新界面尝试手动下载!" 31 && exit 1
geo_v="$(echo "$2" | awk -F "." '{print $1}')_v"
setconfig "$geo_v" "$(date +"%Y%m%d")"
fi
}
}

View File

@@ -0,0 +1,11 @@
#!/bin/sh
# Copyright (C) Juewuy
network_check() { #检查是否联网
for text in 223.5.5.5 1.2.4.8 dns.alidns.com doh.pub; do
ping -c 3 $text >/dev/null 2>&1 && return 0
sleep 5
done
logger "当前设备无法连接网络,已停止启动!" 33
exit 1
}

View File

@@ -0,0 +1,21 @@
clash_check() { #clash启动前检查
#检测vless/hysteria协议
[ "$crashcore" != "meta" ] && [ -n "$(cat $core_config | grep -oE 'type: vless|type: hysteria')" ] && core_exchange meta 'vless/hy协议'
#检测是否存在高级版规则或者tun模式
if [ "$crashcore" = "clash" ]; then
[ -n "$(cat $core_config | grep -aiE '^script:|proxy-providers|rule-providers|rule-set')" ] ||
[ "$redir_mod" = "混合模式" ] ||
[ "$redir_mod" = "Tun模式" ] && core_exchange meta '当前内核不支持的配置'
fi
[ "$crashcore" = "clash" ] && [ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '0:7890' /etc/passwd)" ] &&
core_exchange meta '当前内核不支持非root用户启用本机代理'
check_core
#预下载GeoIP数据库并排除存在自定义数据库链接的情况
[ -n "$(grep -oEi 'geoip:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geoip:|mmdb:' "$CRASHDIR"/yamls/*.yaml)" ] && check_geo Country.mmdb cn_mini.mmdb
#预下载GeoSite数据库并排除存在自定义数据库链接的情况
[ -n "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && [ -z "$(grep -oEi 'geosite:' "$CRASHDIR"/yamls/*.yaml)" ] && check_geo GeoSite.dat geosite.dat
#预下载cn.mrs数据库
[ -n "$(cat "$CRASHDIR"/yamls/*.yaml | grep -oEi 'rule_set.*cn')" ] || [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && check_geo ruleset/cn.mrs mrs_geosite_cn.mrs
return 0
}

View File

@@ -0,0 +1,41 @@
#!/bin/sh
# Copyright (C) Juewuy
check_config() { #检查clash配置文件
#检测节点或providers
sed -n "/^proxies:/,/^[a-z]/ { /^[a-z]/d; p; }" "$core_config_new" >"$TMPDIR"/proxies.yaml
if ! grep -Eq 'server:|server":|server'\'':' "$TMPDIR"/proxies.yaml && ! grep -q 'proxy-providers:' "$core_config_new"; then
echo "-----------------------------------------------"
logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31
cat "$TMPDIR"/proxies.yaml
sleep 1
echo "-----------------------------------------------"
echo "请尝试使用6-2或者6-3的方式生成配置文件"
exit 1
fi
rm -rf "$TMPDIR"/proxies.yaml
#检测旧格式
if cat "$core_config_new" | grep 'Proxy Group:' >/dev/null; then
echo "-----------------------------------------------"
logger "已经停止对旧格式配置文件的支持!!!" 31
echo -e "请使用新格式或者使用【在线生成配置文件】功能!"
echo "-----------------------------------------------"
exit 1
fi
#检测不支持的加密协议
if cat "$core_config_new" | grep 'cipher: chacha20,' >/dev/null; then
echo "-----------------------------------------------"
logger "已停止支持chacha20加密请更换更安全的节点加密协议" 31
echo "-----------------------------------------------"
exit 1
fi
#检测并去除无效策略组
[ -n "$url_type" ] && ckcmd xargs && {
cat "$core_config_new" | sed '/^rules:/,$d' | grep -A 15 "\- name:" | xargs | sed 's/- name: /\n/g' | sed 's/ type: .*proxies: /#/g' | sed 's/- //g' | grep -E '#DIRECT $|#DIRECT$' | grep -Ev '全球直连|direct|Direct' | awk -F '#' '{print $1}' >"$TMPDIR"/clash_proxies
while read line; do
sed -i "/- $line/d" "$core_config_new"
sed -i "/- name: $line/,/- DIRECT/d" "$core_config_new"
done <"$TMPDIR"/clash_proxies
rm -rf "$TMPDIR"/clash_proxies
}
}

View File

@@ -0,0 +1,236 @@
#!/bin/sh
# Copyright (C) Juewuy
#默认dns
[ -z "$dns_nameserver" ] && dns_nameserver='223.5.5.5, 1.2.4.8'
[ -z "$dns_fallback" ] && dns_fallback="1.1.1.1, 8.8.8.8"
[ -z "$dns_resolver" ] && dns_resolver="223.5.5.5, 2400:3200::1"
#修饰clash配置文件
modify_yaml() {
##########需要变更的配置###########
[ "$ipv6_dns" != "未开启" ] && dns_v6='true' || dns_v6='false'
external="external-controller: 0.0.0.0:$db_port"
if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ]; then
[ "$crashcore" = 'meta' ] && tun_meta=', device: utun, auto-route: false, auto-detect-interface: false'
tun="tun: {enable: true, stack: system$tun_meta}"
else
tun='tun: {enable: false}'
fi
exper='experimental: {ignore-resolve-fail: true, interface-name: en0}'
#Meta内核专属配置
[ "$crashcore" = 'meta' ] && {
[ "$redir_mod" != "纯净模式" ] && [ -z "$(grep 'PROCESS' "$CRASHDIR"/yamls/*.yaml)" ] && find_process='find-process-mode: "off"'
}
#dns配置
[ -z "$(cat "$CRASHDIR"/yamls/user.yaml 2>/dev/null | grep '^dns:')" ] && {
[ "$crashcore" != meta ] && dns_resolver='223.5.5.5'
cat >"$TMPDIR"/dns.yaml <<EOF
dns:
enable: true
listen: :$dns_port
use-hosts: true
ipv6: $dns_v6
default-nameserver: [ $dns_resolver ]
enhanced-mode: fake-ip
fake-ip-range: 28.0.0.0/8
fake-ip-range6: fc00::/16
fake-ip-filter:
EOF
if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "fake-ip" ]; then
cat "$CRASHDIR"/configs/fake_ip_filter "$CRASHDIR"/configs/fake_ip_filter.list 2>/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 <<EOF
respect-rules: true
nameserver-policy: {'rule-set:cn': [ $dns_nameserver ]}
proxy-server-nameserver : [ $dns_resolver ]
nameserver: [ $dns_final ]
EOF
else
cat >>"$TMPDIR"/dns.yaml <<EOF
nameserver: [ $dns_nameserver ]
EOF
fi
}
#域名嗅探配置
[ "$sniffer" = "已启用" ] && [ "$crashcore" = "meta" ] && sniffer_set="sniffer: {enable: true, parse-pure-ip: true, skip-domain: [Mijia Cloud], sniff: {http: {ports: [80, 8080-8880], override-destination: true}, tls: {ports: [443, 8443]}, quic: {ports: [443, 8443]}}}"
[ "$crashcore" = "clashpre" ] && [ "$dns_mod" = "redir_host" -o "$sniffer" = "已启用" ] && exper="experimental: {ignore-resolve-fail: true, interface-name: en0,sniff-tls-sni: true}"
#生成set.yaml
cat >"$TMPDIR"/set.yaml <<EOF
mixed-port: $mix_port
redir-port: $redir_port
tproxy-port: $tproxy_port
authentication: ["$authentication"]
allow-lan: true
mode: Rule
log-level: info
ipv6: true
external-controller: :$db_port
external-ui: ui
external-ui-url: "$external_ui_url"
secret: $secret
$tun
$exper
$sniffer_set
$find_process
routing-mark: $routing_mark
EOF
#读取本机hosts并生成配置文件
if [ "$hosts_opt" != "未启用" ] && [ -z "$(grep -aE '^hosts:' "$CRASHDIR"/yamls/user.yaml 2>/dev/null)" ]; then
#NTP劫持
cat >"$TMPDIR"/hosts.yaml <<EOF
use-system-hosts: true
hosts:
'time.android.com': 203.107.6.88
'time.facebook.com': 203.107.6.88
EOF
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 sub-rules listeners'
for char in $yaml_char; do
sed -n "/^$char:/,/^[a-z]/ { /^[a-z]/d; p; }" $core_config >"$TMPDIR"/${char}.yaml
done
#跳过本地tls证书验证
[ "$skip_cert" != "未开启" ] && sed -i 's/skip-cert-verify: false/skip-cert-verify: true/' "$TMPDIR"/proxies.yaml ||
sed -i 's/skip-cert-verify: true/skip-cert-verify: false/' "$TMPDIR"/proxies.yaml
#插入自定义策略组
sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml
sed -i "/#自定义策略组/d" "$TMPDIR"/proxy-groups.yaml
[ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxy-groups.yaml 2>/dev/null)" ] && {
#获取空格数
space_name=$(grep -aE '^ *- \{?name: ' "$TMPDIR"/proxy-groups.yaml | head -n 1 | grep -oE '^ *')
space_proxy="$space_name "
#合并自定义策略组到proxy-groups.yaml
cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml
cat "$TMPDIR"/proxy-groups.yaml >>"$TMPDIR"/proxy-groups_add.yaml
mv -f "$TMPDIR"/proxy-groups_add.yaml "$TMPDIR"/proxy-groups.yaml
oldIFS="$IFS"
grep "\- name: " "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | while read line; do #将自定义策略组插入现有的proxy-group
new_group=$(echo $line | grep -Eo '^ *- name:.*#' | cut -d'#' -f1 | sed 's/.*name: //g')
proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//")
IFS="#"
for name in $proxy_groups; do
line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号
[ -n "$line_a" ] && {
line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号
line_c=$((line_a + line_b - 1)) #计算需要插入的行号
space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数
[ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${new_group} #自定义策略组" "$TMPDIR"/proxy-groups.yaml
}
done
IFS="$oldIFS"
done
}
#插入自定义代理
sed -i "/#自定义代理/d" "$TMPDIR"/proxies.yaml
sed -i "/#自定义代理/d" "$TMPDIR"/proxy-groups.yaml
[ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxies.yaml 2>/dev/null)" ] && {
space_proxy=$(cat "$TMPDIR"/proxies.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') #获取空格数
cat "$CRASHDIR"/yamls/proxies.yaml | sed "s/^ *- /${space_proxy}- /g" | sed "/^#/d" | sed "/^ *$/d" | sed 's/#.*/ #自定义代理/g' >>"$TMPDIR"/proxies.yaml #插入节点
oldIFS="$IFS"
cat "$CRASHDIR"/yamls/proxies.yaml | sed "/^#/d" | while read line; do #将节点插入proxy-group
proxy_name=$(echo $line | grep -Eo 'name: .+, ' | cut -d',' -f1 | sed 's/name: //g')
proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//")
IFS="#"
for name in $proxy_groups; do
line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号
[ -n "$line_a" ] && {
line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号
line_c=$((line_a + line_b - 1)) #计算需要插入的行号
space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数
[ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${proxy_name} #自定义代理" "$TMPDIR"/proxy-groups.yaml
}
done
IFS="$oldIFS"
done
}
#添加自定义入站
[ "$vms_service" = ON ] || [ "$sss_service" = ON ] && {
. "$CRASHDIR"/configs/gateway.cfg
. "$CRASHDIR"/libs/meta_listeners.sh
}
#节点绕过功能支持
sed -i "/#节点绕过/d" "$TMPDIR"/rules.yaml
[ "$proxies_bypass" = "已启用" ] && {
cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '!a[$0]++' | sed 's/^/\ -\ IP-CIDR,/g' | sed 's|$|/32,DIRECT,no-resolve #节点绕过|g' >>"$TMPDIR"/proxies_bypass
cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -vE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?' | awk '!a[$0]++' | sed 's/^/\ -\ DOMAIN,/g' | sed 's/$/,DIRECT #节点绕过/g' >>"$TMPDIR"/proxies_bypass
cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/proxies_bypass
mv -f "$TMPDIR"/proxies_bypass "$TMPDIR"/rules.yaml
}
#插入自定义规则
sed -i "/#自定义规则/d" "$TMPDIR"/rules.yaml
[ -s "$CRASHDIR"/yamls/rules.yaml ] && {
cat "$CRASHDIR"/yamls/rules.yaml | sed "/^#/d" | sed '$a\' | sed 's/$/ #自定义规则/g' >"$TMPDIR"/rules.add
cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/rules.add
mv -f "$TMPDIR"/rules.add "$TMPDIR"/rules.yaml
}
#mix和route模式生成rule-providers
[ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && ! grep -q 'cn:' "$TMPDIR"/rule-providers.yaml && ! grep -q '^rule-providers' "$CRASHDIR"/yamls/others.yaml 2>/dev/null && {
space=$(sed -n "1p" "$TMPDIR"/rule-providers.yaml | grep -oE '^ *') #获取空格数
[ -z "$space" ] && space=' '
echo "${space}cn: {type: http, behavior: domain, format: mrs, path: ./ruleset/cn.mrs, url: https://testingcf.jsdelivr.net/gh/juewuy/ShellCrash@update/bin/geodata/mrs_geosite_cn.mrs}" >>"$TMPDIR"/rule-providers.yaml
}
#对齐rules中的空格
sed -i 's/^ *-/ -/g' "$TMPDIR"/rules.yaml
#合并文件
[ -s "$CRASHDIR"/yamls/user.yaml ] && {
yaml_user="$CRASHDIR"/yamls/user.yaml
#set和user去重,且优先使用user.yaml
cp -f "$TMPDIR"/set.yaml "$TMPDIR"/set_bak.yaml
for char in mode allow-lan log-level tun experimental external-ui-url interface-name dns store-selected; do
[ -n "$(grep -E "^$char" $yaml_user)" ] && sed -i "/^$char/d" "$TMPDIR"/set.yaml
done
}
[ -s "$TMPDIR"/dns.yaml ] && yaml_dns="$TMPDIR"/dns.yaml
[ -s "$TMPDIR"/hosts.yaml ] && yaml_hosts="$TMPDIR"/hosts.yaml
[ -s "$CRASHDIR"/yamls/others.yaml ] && yaml_others="$CRASHDIR"/yamls/others.yaml
yaml_add=
for char in $yaml_char; do #将额外配置文件合并
[ -s "$TMPDIR"/${char}.yaml ] && {
sed -i "1i\\${char}:" "$TMPDIR"/${char}.yaml
yaml_add="$yaml_add $TMPDIR/${char}.yaml"
}
done
#合并完整配置文件
cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_hosts $yaml_user $yaml_others $yaml_add >"$TMPDIR"/config.yaml
#测试自定义配置文件
"$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml >/dev/null
if [ "$?" != 0 ]; then
logger "$("$TMPDIR"/CrashCore -t -d "$BINDIR" -f "$TMPDIR"/config.yaml | grep -Eo 'error.*=.*')" 31
logger "自定义配置文件校验失败!将使用基础配置文件启动!" 33
logger "错误详情请参考 "$TMPDIR"/error.yaml 文件!" 33
mv -f "$TMPDIR"/config.yaml "$TMPDIR"/error.yaml >/dev/null 2>&1
sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml
mv -f "$TMPDIR"/set_bak.yaml "$TMPDIR"/set.yaml >/dev/null 2>&1
#合并基础配置文件
cut -c 1- "$TMPDIR"/set.yaml $yaml_dns $yaml_add >"$TMPDIR"/config.yaml
sed -i "/#自定义/d" "$TMPDIR"/config.yaml
fi
#建立软连接
[ ""$TMPDIR"" = ""$BINDIR"" ] || ln -sf "$TMPDIR"/config.yaml "$BINDIR"/config.yaml 2>/dev/null || cp -f "$TMPDIR"/config.yaml "$BINDIR"/config.yaml
#清理缓存
for char in $yaml_char set set_bak dns hosts; do
rm -f "$TMPDIR"/${char}.yaml
done
}

View File

@@ -0,0 +1,103 @@
#!/bin/sh
# Copyright (C) Juewuy
. "$CRASHDIR"/libs/urlencode.sh
. "$CRASHDIR"/libs/check_target.sh
. "$CRASHDIR"/libs/web_get_bin.sh
. "$CRASHDIR"/libs/compare.sh
. "$CRASHDIR"/libs/set_config.sh
update_servers() { #更新servers.list
get_bin "$TMPDIR"/servers.list public/servers.list
[ "$?" = 0 ] && mv -f "$TMPDIR"/servers.list "$CRASHDIR"/configs/servers.list
}
gen_ua(){ #自动生成ua
[ -z "$user_agent" -o "$user_agent" = "auto" ] && {
if echo "$crashcore" | grep -q 'singbox'; then
user_agent="sing-box/singbox/$core_v"
elif [ "$crashcore" = meta ]; then
user_agent="clash.meta/mihomo/$core_v"
else
user_agent="clash"
fi
}
[ "$user_agent" = "none" ] && unset user_agent
}
get_core_config() { #下载内核配置文件
[ -z "$rule_link" ] && rule_link=1
[ -z "$server_link" ] || [ $server_link -gt $(grep -aE '^4' "$CRASHDIR"/configs/servers.list | wc -l) ] && server_link=1
Server=$(grep -aE '^3|^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $3}')
Server_ua=$(grep -aE '^4' "$CRASHDIR"/configs/servers.list | sed -n ""$server_link"p" | awk '{print $4}')
Config=$(grep -aE '^5' "$CRASHDIR"/configs/servers.list | sed -n ""$rule_link"p" | awk '{print $3}')
gen_ua
#如果传来的是Url链接则合成Https链接否则直接使用Https链接
if [ -z "$Https" ]; then
#Urlencord转码处理保留字符
if ckcmd hexdump;then
Url=$(echo $Url | sed 's/%26/\&/g') #处理分隔符
urlencodeUrl="exclude=$(urlencode "$exclude")&include=$(urlencode "$include")&url=$(urlencode "$Url")&config=$(urlencode "$Config")"
else
urlencodeUrl="exclude=$exclude&include=$include&url=$Url&config=$Config"
fi
Https="${Server}/sub?target=${target}&${Server_ua}=${user_agent}&insert=true&new_name=true&scv=true&udp=true&${urlencodeUrl}"
url_type=true
fi
#输出
echo "-----------------------------------------------"
logger "正在连接服务器获取【$target】配置文件…………"
echo -e "链接地址为:\033[4;32m$Https\033[0m"
echo 可以手动复制该链接到浏览器打开并查看数据是否正常!
#获取在线config文件
core_config_new="$TMPDIR"/"$target"_config."$format"
rm -rf "$core_config_new"
webget "$core_config_new" "$Https" echoon rediron skipceron "$user_agent"
if [ "$?" != "0" ]; then
if [ -z "$url_type" ]; then
echo "-----------------------------------------------"
logger "配置文件获取失败!" 31
echo -e "\033[31m请尝试使用【在线生成配置文件】功能\033[0m"
echo "-----------------------------------------------"
exit 1
else
if [ -n "$retry" ] && [ "$retry" -ge 3 ]; then
logger "无法获取配置文件,请检查链接格式以及网络连接状态!" 31
echo -e "\033[32m也可用浏览器下载以上链接后使用WinSCP手动上传到/tmp目录后执行crash命令本地导入\033[0m"
exit 1
else
retry=$((retry + 1))
logger "配置文件获取失败!" 31
if [ "$retry" = 1 ]; then
echo -e "\033[32m尝试更新服务器列表并使用其他服务器获取配置\033[0m"
update_servers
else
echo -e "\033[32m尝试使用其他服务器获取配置\033[0m"
fi
echo -e "正在重试\033[33m第$retry次/共3次\033[0m"
if [ "$server_link" -ge 4 ]; then
server_link=0
fi
server_link=$((server_link + 1))
setconfig server_link $server_link
Https=""
get_core_config
fi
fi
else
Https=""
if echo "$crashcore" | grep -q 'singbox'; then
. "$CRASHDIR"/starts/singbox_config_check.sh
else
. "$CRASHDIR"/starts/clash_config_check.sh
fi
check_config
#如果不同则备份并替换文件
if [ -s "$core_config" ]; then
compare "$core_config_new" "$core_config"
[ "$?" = 0 ] || mv -f "$core_config" "$core_config".bak && mv -f "$core_config_new" "$core_config"
else
mv -f "$core_config_new" "$core_config"
fi
echo -e "\033[32m已成功获取配置文件\033[0m"
fi
return 0
}

View File

@@ -0,0 +1,11 @@
core_exchange() { #升级为高级内核
#$1目标内核 $2提示语句
logger "检测到${2}!将改为使用${1}核心启动!" 33
rm -rf "$TMPDIR"/CrashCore
rm -rf "$BINDIR"/CrashCore
rm -rf "$BINDIR"/CrashCore.tar.gz
crashcore="$1"
setconfig crashcore "$1"
echo "-----------------------------------------------"
}

View File

@@ -0,0 +1,27 @@
getlanip() { #获取局域网host地址
i=1
while [ "$i" -le "20" ]; do
host_ipv4=$(ip a 2>&1 | grep -w 'inet' | grep 'global' | grep 'brd' | grep -Ev 'utun|iot|peer|docker|podman|virbr|vnet|ovs|vmbr|veth|vmnic|vboxnet|lxcbr|xenbr|vEthernet' | grep -E ' 1(92|0|72)\.' | sed 's/.*inet.//g' | sed 's/br.*$//g' | sed 's/metric.*$//g') #ipv4局域网网段
[ "$ipv6_redir" = "已开启" ] && host_ipv6=$(ip a 2>&1 | grep -w 'inet6' | grep -E 'global' | sed 's/.*inet6.//g' | sed 's/scope.*$//g') #ipv6公网地址段
[ -f "$TMPDIR"/ShellCrash.log ] && break
[ -n "$host_ipv4" -a "$ipv6_redir" != "已开启" ] && break
[ -n "$host_ipv4" -a -n "$host_ipv6" ] && break
sleep 1 && i=$((i + 1))
done
#添加自定义ipv4局域网网段
if [ "$replace_default_host_ipv4" == "已启用" ]; then
host_ipv4="$cust_host_ipv4"
else
host_ipv4="$host_ipv4$cust_host_ipv4"
fi
#缺省配置
[ -z "$host_ipv4" ] && host_ipv4='192.168.0.0/16 10.0.0.0/12 172.16.0.0/12'
host_ipv6="fe80::/10 fd00::/8 $host_ipv6"
#获取本机出口IP地址
local_ipv4=$(ip route 2>&1 | grep -Ev 'utun|iot|docker|linkdown' | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u)
[ -z "$local_ipv4" ] && local_ipv4=$(ip route 2>&1 | grep -Eo 'src.*' | grep -Eo '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sort -u)
#保留地址
[ -z "$reserve_ipv4" ] && reserve_ipv4="0.0.0.0/8 10.0.0.0/8 127.0.0.0/8 100.64.0.0/10 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4"
[ -z "$reserve_ipv6" ] && reserve_ipv6="::/128 ::1/128 ::ffff:0:0/96 64:ff9b::/96 100::/64 2001::/32 2001:20::/28 2001:db8::/32 2002::/16 fe80::/10 ff00::/8"
}

View File

@@ -130,6 +130,8 @@ start_ipt_dns() { #iptables-dns通用工具
"$1" $w -t nat -I "$2" -p udp --dport 53 -j "$3"
}
start_ipt_wan() { #iptables公网防火墙
ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables
ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables
ipt_wan_accept(){
$iptable -I INPUT -p "$1" -m multiport --dports "$fw_wan_ports" -j ACCEPT
ckcmd ip6tables && $ip6table -I INPUT -p "$1" -m multiport --dports "$fw_wan_ports" -j ACCEPT

View File

@@ -1,42 +1,49 @@
#!/bin/sh
# Copyright (C) Juewuy
#路由规则总入口
start_firewall() {
getlanip #获取局域网host地址
#设置策略路由
[ "$firewall_area" != 4 ] && {
[ "$redir_mod" = "Tproxy模式" ] && ip route add local default dev lo table $table 2>/dev/null
[ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && {
i=1
while [ -z "$(ip route list | grep utun)" -a "$i" -le 29 ]; do
sleep 1
i=$((i + 1))
done
if [ -z "$(ip route list | grep utun)" ]; then
logger "找不到tun模块放弃启动tun相关防火墙规则" 31
else
ip route add default dev utun table $table && tun_statu=true
fi
}
[ "$firewall_area" = 5 ] && ip route add default via $bypass_host table $table 2>/dev/null
[ "$redir_mod" != "Redir模式" ] && ip rule add fwmark $fwmark table $table 2>/dev/null
}
#添加ipv6路由
[ "$ipv6_redir" = "已开启" -a "$firewall_area" -le 3 ] && {
[ "$redir_mod" = "Tproxy模式" ] && ip -6 route add local default dev lo table $((table + 1)) 2>/dev/null
[ -n "$(ip route list | grep utun)" ] && ip -6 route add default dev utun table $((table + 1)) 2>/dev/null
[ "$redir_mod" != "Redir模式" ] && ip -6 rule add fwmark $fwmark table $((table + 1)) 2>/dev/null
}
#判断代理用途
[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && local_proxy=true
[ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 ] && lan_proxy=true
#防火墙配置
[ "$firewall_mod" = 'iptables' ] && . "$CRASHDIR"/starts/fw_iptables.sh && start_iptables
[ "$firewall_mod" = 'nftables' ] && . "$CRASHDIR"/starts/fw_nftables.sh && start_nftables
#修复部分虚拟机dns查询失败的问题
[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ "$systype" != 'container' ] && {
line=$(grep -n 'nameserver' /etc/resolv.conf | awk -F: 'FNR==1{print $1}')
sed -i "$line i\nameserver 127.0.0.1 #shellcrash-dns-repair" /etc/resolv.conf >/dev/null 2>&1
}
#获取局域网host地址
. "$CRASHDIR"/starts/fw_getlanip.sh && getlanip
#缺省值
[ -z "$macfilter_type" ] && macfilter_type='黑名单'
[ -z "$common_ports" ] && common_ports='已开启'
[ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443'
[ "$common_ports" = "已开启" ] && ports="-m multiport --dports $multiport"
[ -z "$redir_mod" ] && [ "$USER" = "root" -o "$USER" = "admin" ] && redir_mod='Redir模式'
[ -z "$dns_mod" ] && dns_mod='redir_host'
[ -z "$redir_mod" ] && firewall_area='4'
#设置策略路由
[ "$firewall_area" != 4 ] && {
[ "$redir_mod" = "Tproxy模式" ] && ip route add local default dev lo table $table 2>/dev/null
[ "$redir_mod" = "Tun模式" -o "$redir_mod" = "混合模式" ] && {
i=1
while [ -z "$(ip route list | grep utun)" -a "$i" -le 29 ]; do
sleep 1
i=$((i + 1))
done
if [ -z "$(ip route list | grep utun)" ]; then
logger "找不到tun模块放弃启动tun相关防火墙规则" 31
else
ip route add default dev utun table $table && tun_statu=true
fi
}
[ "$firewall_area" = 5 ] && ip route add default via $bypass_host table $table 2>/dev/null
[ "$redir_mod" != "Redir模式" ] && ip rule add fwmark $fwmark table $table 2>/dev/null
}
#添加ipv6路由
[ "$ipv6_redir" = "已开启" -a "$firewall_area" -le 3 ] && {
[ "$redir_mod" = "Tproxy模式" ] && ip -6 route add local default dev lo table $((table + 1)) 2>/dev/null
[ -n "$(ip route list | grep utun)" ] && ip -6 route add default dev utun table $((table + 1)) 2>/dev/null
[ "$redir_mod" != "Redir模式" ] && ip -6 rule add fwmark $fwmark table $((table + 1)) 2>/dev/null
}
#判断代理用途
[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && local_proxy=true
[ "$firewall_area" = 1 -o "$firewall_area" = 3 -o "$firewall_area" = 5 ] && lan_proxy=true
#防火墙配置
[ "$firewall_mod" = 'iptables' ] && . "$CRASHDIR"/starts/fw_iptables.sh && start_iptables
[ "$firewall_mod" = 'nftables' ] && . "$CRASHDIR"/starts/fw_nftables.sh && start_nftables
#修复部分虚拟机dns查询失败的问题
[ "$firewall_area" = 2 -o "$firewall_area" = 3 ] && [ -z "$(grep '127.0.0.1' /etc/resolv.conf 2>/dev/null)" ] && [ "$systype" != 'container' ] && {
line=$(grep -n 'nameserver' /etc/resolv.conf | awk -F: 'FNR==1{print $1}')
sed -i "$line i\nameserver 127.0.0.1 #shellcrash-dns-repair" /etc/resolv.conf >/dev/null 2>&1
}

View File

@@ -1,130 +1,136 @@
#!/bin/sh
# Copyright (C) Juewuy
#还原防火墙配置
stop_firewall() {
#获取局域网host地址
getlanip
#重置iptables相关规则
ckcmd iptables && {
#dns
$iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_dns 2>/dev/null
$iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_dns 2>/dev/null
$iptable -t nat -D OUTPUT -p udp --dport 53 -j shellcrash_dns_out 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp --dport 53 -j shellcrash_dns_out 2>/dev/null
#redir
$iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash 2>/dev/null
$iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp $ports -j shellcrash_out 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_out 2>/dev/null
#vm_dns
$iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_vm_dns 2>/dev/null
$iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_vm_dns 2>/dev/null
#vm_redir
$iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash_vm 2>/dev/null
$iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_vm 2>/dev/null
#TPROXY&tun
$iptable -t mangle -D PREROUTING -p tcp $ports -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p udp $ports -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p udp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D OUTPUT -p tcp $ports -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p udp $ports -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p udp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null
$iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null
#tun
$iptable -D FORWARD -o utun -j ACCEPT 2>/dev/null
#屏蔽QUIC
[ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && set_cn_ip='-m set ! --match-set cn_ip dst'
$iptable -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null
$iptable -D FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT 2>/dev/null
#公网访问
$iptable -D INPUT -i lo -j ACCEPT 2>/dev/null
$iptable -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$iptable -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
$iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
#清理shellcrash自建表
for words in shellcrash_dns shellcrash shellcrash_out shellcrash_dns_out shellcrash_vm shellcrash_vm_dns; do
$iptable -t nat -F $words 2>/dev/null
$iptable -t nat -X $words 2>/dev/null
done
for words in shellcrash_mark shellcrash_mark_out; do
$iptable -t mangle -F $words 2>/dev/null
$iptable -t mangle -X $words 2>/dev/null
done
}
#重置ipv6规则
ckcmd ip6tables && {
#dns
$ip6table -t nat -D PREROUTING -p tcp --dport 53 -j shellcrashv6_dns 2>/dev/null
$ip6table -t nat -D PREROUTING -p udp --dport 53 -j shellcrashv6_dns 2>/dev/null
#redir
$ip6table -t nat -D PREROUTING -p tcp $ports -j shellcrashv6 2>/dev/null
$ip6table -t nat -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6 2>/dev/null
$ip6table -t nat -D OUTPUT -p tcp $ports -j shellcrashv6_out 2>/dev/null
$ip6table -t nat -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_out 2>/dev/null
$ip6table -D INPUT -p tcp --dport 53 -j REJECT 2>/dev/null
$ip6table -D INPUT -p udp --dport 53 -j REJECT 2>/dev/null
#mark
$ip6table -t mangle -D PREROUTING -p tcp $ports -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p udp $ports -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p udp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D OUTPUT -p tcp $ports -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p udp $ports -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p udp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null
$ip6table -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null
$ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null
$ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null
#tun
$ip6table -D FORWARD -o utun -j ACCEPT 2>/dev/null
#屏蔽QUIC
[ "$dns_mod" != "fake-ip" -a "$cn_ip_route" = "已开启" ] && set_cn_ip6='-m set ! --match-set cn_ip6 dst'
$ip6table -D INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT 2>/dev/null
$ip6table -D FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT 2>/dev/null
#公网访问
$ip6table -D INPUT -i lo -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
$ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
#清理shellcrash自建表
for words in shellcrashv6_dns shellcrashv6 shellcrashv6_out; do
$ip6table -t nat -F $words 2>/dev/null
$ip6table -t nat -X $words 2>/dev/null
done
for words in shellcrashv6_mark shellcrashv6_mark_out; do
$ip6table -t mangle -F $words 2>/dev/null
$ip6table -t mangle -X $words 2>/dev/null
done
$ip6table -t mangle -F shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -X shellcrashv6_mark 2>/dev/null
}
#清理ipset规则
ipset destroy cn_ip >/dev/null 2>&1
ipset destroy cn_ip6 >/dev/null 2>&1
#移除dnsmasq转发规则
[ "$dns_redir" = "已开启" ] && {
uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1
uci set dhcp.@dnsmasq[0].noresolv=0 2>/dev/null
uci commit dhcp >/dev/null 2>&1
/etc/init.d/dnsmasq restart >/dev/null 2>&1
}
#清理路由规则
ip rule del fwmark $fwmark table $table 2>/dev/null
ip route flush table $table 2>/dev/null
ip -6 rule del fwmark $fwmark table $((table + 1)) 2>/dev/null
ip -6 route flush table $((table + 1)) 2>/dev/null
#重置nftables相关规则
ckcmd nft && {
nft flush table inet shellcrash >/dev/null 2>&1
nft delete table inet shellcrash >/dev/null 2>&1
}
#还原防火墙文件
[ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall
#others
[ "$systype" != 'container' ] && sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf >/dev/null 2>&1
. "$CRASHDIR"/configs/ShellCrash.cfg
. "$CRASHDIR"/starts/fw_getlanip.sh && getlanip #获取局域网host地址
#缺省值
[ -z "$common_ports" ] && common_ports='已开启'
[ -z "$multiport" ] && multiport='22,80,143,194,443,465,587,853,993,995,5222,8080,8443'
[ "$common_ports" = "已开启" ] && ports="-m multiport --dports $multiport"
#重置iptables相关规则
ckcmd iptables && {
ckcmd iptables && iptables -h | grep -q '\-w' && iptable='iptables -w' || iptable=iptables
#dns
$iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_dns 2>/dev/null
$iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_dns 2>/dev/null
$iptable -t nat -D OUTPUT -p udp --dport 53 -j shellcrash_dns_out 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp --dport 53 -j shellcrash_dns_out 2>/dev/null
#redir
$iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash 2>/dev/null
$iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp $ports -j shellcrash_out 2>/dev/null
$iptable -t nat -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_out 2>/dev/null
#vm_dns
$iptable -t nat -D PREROUTING -p tcp --dport 53 -j shellcrash_vm_dns 2>/dev/null
$iptable -t nat -D PREROUTING -p udp --dport 53 -j shellcrash_vm_dns 2>/dev/null
#vm_redir
$iptable -t nat -D PREROUTING -p tcp $ports -j shellcrash_vm 2>/dev/null
$iptable -t nat -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_vm 2>/dev/null
#TPROXY&tun
$iptable -t mangle -D PREROUTING -p tcp $ports -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p udp $ports -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p tcp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D PREROUTING -p udp -d 28.0.0.0/8 -j shellcrash_mark 2>/dev/null
$iptable -t mangle -D OUTPUT -p tcp $ports -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p udp $ports -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p tcp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D OUTPUT -p udp -d 28.0.0.0/8 -j shellcrash_mark_out 2>/dev/null
$iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null
$iptable -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null
#tun
$iptable -D FORWARD -o utun -j ACCEPT 2>/dev/null
#屏蔽QUIC
[ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" != "未开启" ] && set_cn_ip='-m set ! --match-set cn_ip dst'
$iptable -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null
$iptable -D FORWARD -p udp --dport 443 -o utun $set_cn_ip -j REJECT 2>/dev/null
#公网访问
$iptable -D INPUT -i lo -j ACCEPT 2>/dev/null
$iptable -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$iptable -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$iptable -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
$iptable -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
#清理shellcrash自建表
for text in shellcrash_dns shellcrash shellcrash_out shellcrash_dns_out shellcrash_vm shellcrash_vm_dns; do
$iptable -t nat -F "$text" 2>/dev/null
$iptable -t nat -X "$text" 2>/dev/null
done
for text in shellcrash_mark shellcrash_mark_out; do
$iptable -t mangle -F "$text" 2>/dev/null
$iptable -t mangle -X "$text" 2>/dev/null
done
}
#重置ipv6规则
ckcmd ip6tables && {
ckcmd ip6tables && ip6tables -h | grep -q '\-w' && ip6table='ip6tables -w' || ip6table=ip6tables
#dns
$ip6table -t nat -D PREROUTING -p tcp --dport 53 -j shellcrashv6_dns 2>/dev/null
$ip6table -t nat -D PREROUTING -p udp --dport 53 -j shellcrashv6_dns 2>/dev/null
#redir
$ip6table -t nat -D PREROUTING -p tcp $ports -j shellcrashv6 2>/dev/null
$ip6table -t nat -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6 2>/dev/null
$ip6table -t nat -D OUTPUT -p tcp $ports -j shellcrashv6_out 2>/dev/null
$ip6table -t nat -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_out 2>/dev/null
$ip6table -D INPUT -p tcp --dport 53 -j REJECT 2>/dev/null
$ip6table -D INPUT -p udp --dport 53 -j REJECT 2>/dev/null
#mark
$ip6table -t mangle -D PREROUTING -p tcp $ports -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p udp $ports -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p tcp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D PREROUTING -p udp -d fc00::/16 -j shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -D OUTPUT -p tcp $ports -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p udp $ports -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p tcp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null
$ip6table -t mangle -D OUTPUT -p udp -d fc00::/16 -j shellcrashv6_mark_out 2>/dev/null
$ip6table -D INPUT -p udp --dport 443 $set_cn_ip -j REJECT 2>/dev/null
$ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p tcp -j TPROXY --on-port $tproxy_port 2>/dev/null
$ip6table -t mangle -D PREROUTING -m mark --mark $fwmark -p udp -j TPROXY --on-port $tproxy_port 2>/dev/null
#tun
$ip6table -D FORWARD -o utun -j ACCEPT 2>/dev/null
#屏蔽QUIC
[ "$dns_mod" != "fake-ip" ] && [ "$cn_ip_route" != "未开启" ] && set_cn_ip6='-m set ! --match-set cn_ip6 dst'
$ip6table -D INPUT -p udp --dport 443 $set_cn_ip6 -j REJECT 2>/dev/null
$ip6table -D FORWARD -p udp --dport 443 -o utun $set_cn_ip6 -j REJECT 2>/dev/null
#公网访问
$ip6table -D INPUT -i lo -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p tcp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p udp -m multiport --dports "$fw_wan_ports" -j ACCEPT 2>/dev/null
$ip6table -D INPUT -p tcp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
$ip6table -D INPUT -p udp -m multiport --dports "$mix_port,$db_port,$dns_port" -j REJECT 2>/dev/null
#清理shellcrash自建表
for text in shellcrashv6_dns shellcrashv6 shellcrashv6_out; do
$ip6table -t nat -F "$text" 2>/dev/null
$ip6table -t nat -X "$text" 2>/dev/null
done
for text in shellcrashv6_mark shellcrashv6_mark_out; do
$ip6table -t mangle -F "$text" 2>/dev/null
$ip6table -t mangle -X "$text" 2>/dev/null
done
$ip6table -t mangle -F shellcrashv6_mark 2>/dev/null
$ip6table -t mangle -X shellcrashv6_mark 2>/dev/null
}
#清理ipset规则
ipset destroy cn_ip >/dev/null 2>&1
ipset destroy cn_ip6 >/dev/null 2>&1
#移除dnsmasq转发规则
[ "$dns_redir" = "已开启" ] && {
uci del dhcp.@dnsmasq[-1].server >/dev/null 2>&1
uci set dhcp.@dnsmasq[0].noresolv=0 2>/dev/null
uci commit dhcp >/dev/null 2>&1
/etc/init.d/dnsmasq restart >/dev/null 2>&1
}
#清理路由规则
ip rule del fwmark $fwmark table $table 2>/dev/null
ip route flush table $table 2>/dev/null
ip -6 rule del fwmark $fwmark table $((table + 1)) 2>/dev/null
ip -6 route flush table $((table + 1)) 2>/dev/null
#重置nftables相关规则
ckcmd nft && {
nft flush table inet shellcrash >/dev/null 2>&1
nft delete table inet shellcrash >/dev/null 2>&1
}
#还原防火墙文件
[ -s /etc/init.d/firewall.bak ] && mv -f /etc/init.d/firewall.bak /etc/init.d/firewall
#others
[ "$systype" != 'container' ] && sed -i '/shellcrash-dns-repair/d' /etc/resolv.conf >/dev/null 2>&1

View File

@@ -0,0 +1,34 @@
#!/bin/sh
# Copyright (C) Juewuy
#初始化目录
CRASHDIR=$(
cd $(dirname $0)
cd ..
pwd
)
profile=/etc/profile
. "$CRASHDIR"/libs/set_profile.sh
. "$CRASHDIR"/libs/set_cron.sh
. "$CRASHDIR"/configs/ShellCrash.cfg
#padavan和华硕环境变量目录设置
if [ -d "/etc/storage/clash" -o -d "/etc/storage/ShellCrash" ]; then
i=1
while [ ! -w /etc/profile -a "$i" -lt 10 ]; do
sleep 3 && i=$((i + 1))
done
[ -w "$profile" ] || profile=/etc_ro/profile
mount -t tmpfs -o remount,rw,size=45M tmpfs /tmp #增加/tmp空间以适配新的内核压缩方式
sed -i '' "$profile" #将软链接转化为一般文件
elif [ -d "/jffs" ]; then
sleep 60
[ -w "$profile" ] || profile=$(cat /etc/profile | grep -oE '\-f.*jffs.*profile' | awk '{print $2}')
fi
#写入环境变量
set_profile "$profile"
#启动进程或删除守护进程
if [ -f "$CRASHDIR"/.dis_startup ];then
cronset "保守模式守护进程"
else
"$CRASHDIR"/start.sh start
fi

View File

@@ -1,73 +0,0 @@
#!/sbin/openrc-run
# 服务名
name="shellcrash"
description="Custom proxy service for ShellCrash"
#获取目录
CRASHDIR=$(cat /etc/profile | grep CRASHDIR | awk -F "\"" '{print $2}')
[ -z "$CRASHDIR" ] && CRASHDIR=$(cat ~/.bashrc | grep CRASHDIR | awk -F "\"" '{print $2}')
source ${CRASHDIR}/configs/command.env #加载启动命令和启动目录
# PID 文件
pidfile="/run/shellcrash.pid"
depend() {
#need net
after firewall
}
start() {
ebegin "Starting ShellCrash service"
# 如果 firewal_area=5 则运行主旁转发脚本
if grep -q 'firewall_area=5' "$CRASHDIR/configs/ShellCrash.cfg" 2>/dev/null; then
"$CRASHDIR/start.sh" start_firewall
eend $? "Firewall start failed"
return
fi
# 确定运行用户shellcrash 或 root
if grep -q 'shellcrash:x:0:7890' /etc/passwd; then
runuser="shellcrash"
else
runuser="root"
fi
# 必要文件检测
"$CRASHDIR/start.sh" bfstart
if [ "$?" != "0" ]; then
eend 1 "bfstart check failed"
return
fi
# 启动主程序(自动守护 + 自动重启)
supervise-daemon "${name}" \
--pidfile "${pidfile}" \
--user "${runuser}" \
--respawn-max 0 \
--respawn-delay 3 \
--start ${COMMAND%% *} -- ${COMMAND#* }
ret=$?
eend $ret
[ $ret -ne 0 ] && return
# 启动后操作
"$CRASHDIR/start.sh" afstart &
}
stop() {
ebegin "Stopping ShellCrash service"
# 停止后台进程
start-stop-daemon --stop \
--pidfile "${pidfile}" \
--retry 5
rm -f "${pidfile}"
# 清理 firewall、proxy
"$CRASHDIR/start.sh" stop_firewall
eend $?
}

View File

@@ -1,38 +0,0 @@
#!/bin/sh /etc/rc.common
START=99
SERVICE_DAEMONIZE=1
SERVICE_WRITE_PID=1
USE_PROCD=1
#获取目录
CRASHDIR=$(cat /etc/profile | grep CRASHDIR | awk -F "\"" '{print $2}')
[ -z "$CRASHDIR" ] && CRASHDIR=$(cat ~/.bashrc | grep CRASHDIR | awk -F "\"" '{print $2}')
source ${CRASHDIR}/configs/command.env #加载启动命令和启动目录
start_service() {
if [ -n "$(cat $CRASHDIR/configs/ShellCrash.cfg | grep 'firewall_area=5')" ]; then
$CRASHDIR/start.sh start_firewall #主旁转发
else
#本机代理用户
[ -n "$(grep 'shellcrash:x:0:7890' /etc/passwd)" ] && USER=shellcrash || USER=root
#检测必须文件
$CRASHDIR/start.sh bfstart
if [ "$?" = "0" ]; then
#使用procd创建clash后台进程
procd_open_instance
procd_set_param user $USER
procd_set_param respawn
procd_set_param command $COMMAND
procd_set_param stderr 0
procd_set_param stdout 0
procd_close_instance
#启动结束执行
$CRASHDIR/start.sh afstart &
fi
fi
}
stop_service() {
procd_close_instance
$CRASHDIR/start.sh stop_firewall
}

View File

@@ -1,20 +0,0 @@
[Unit]
Description=ShellCrash Core
After=network.target
[Service]
Type=simple
User=shellcrash
User=shellcrash
StandardOutput=null
ExecStartPre=/etc/ShellCrash/start.sh bfstart
ExecStart=/etc/ShellCrash/CrashCore run -D /etc/ShellCrash -C /tmp/ShellCrash/jsons >/dev/null
ExecStartPost=/etc/ShellCrash/start.sh afstart
ExecStopPost=/etc/ShellCrash/start.sh stop_firewall
Restart=on-abnormal
RestartSec=10s
LimitNOFILE=infinity
[Install]
WantedBy=multi-user.target

View File

@@ -0,0 +1,13 @@
singbox_check() { #singbox启动前检查
#检测singboxr专属功能
[ "$crashcore" != "singboxr" ] && [ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oE '"shadowsocksr"|"providers"')" ] && {
. "$CRASHDIR"/starts/core_exchange.sh && core_exchange singboxr 'singboxr内核专属功能'
}
check_core
#预下载geoip-cn.srs数据库
[ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"geoip-cn"')" ] && check_geo ruleset/geoip-cn.srs srs_geoip_cn.srs
#预下载cn.srs数据库
[ -n "$(cat "$CRASHDIR"/jsons/*.json | grep -oEi '"rule_set" *: *"cn"')" ] || [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && check_geo ruleset/cn.srs srs_geosite_cn.srs
return 0
}

View File

@@ -0,0 +1,37 @@
#!/bin/sh
# Copyright (C) Juewuy
check_config() { #检查singbox配置文件
#检测节点或providers
if ! grep -qE '"(socks|http|shadowsocks(r)?|vmess|trojan|wireguard|hysteria(2)?|vless|shadowtls|tuic|ssh|tor|providers|anytls|soduku)"' "$core_config_new"; then
echo "-----------------------------------------------"
logger "获取到了配置文件【$core_config_new】,但似乎并不包含正确的节点信息!" 31
echo "请尝试使用6-2或者6-3的方式生成配置文件"
exit 1
fi
#删除不兼容的旧版内容
[ "$(wc -l <"$core_config_new")" -lt 3 ] && {
sed -i 's/^.*"inbounds":/{"inbounds":/' "$core_config_new"
sed -i 's/{[^{}]*"dns-out"[^{}]*}//g' "$core_config_new"
}
#检查不支持的旧版内容
grep -q '"sni"' "$core_config_new" && {
logger "获取到了不支持的旧版(<1.12)配置文件【$core_config_new】!" 31
echo "请尝试使用支持1.12以上版本内核的方式生成配置文件!"
exit 1
}
#检测并去除无效策略组
[ -n "$url_type" ] && {
#获得无效策略组名称
grep -oE '\{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]' "$core_config_new" | sed -n 's/.*"tag":"\([^"]*\)".*/\1/p' >"$TMPDIR"/singbox_tags
#删除策略组
sed -i 's/{"type":"urltest","tag":"[^"]*","outbounds":\["DIRECT"\]}//g; s/{"type":"[^"]*","tag":"[^"]*","outbounds":\["DIRECT"\],"url":"[^"]*","interval":"[^"]*","tolerance":[^}]*}//g' "$core_config_new"
#删除全部包含策略组名称的规则
while read line; do
sed -i "s/\"$line\"//g" "$core_config_new"
done <"$TMPDIR"/singbox_tags
rm -rf "$TMPDIR"/singbox_tags
}
#清理多余逗号
sed -i 's/,\+/,/g; s/\[,/\[/g; s/,]/]/g' "$core_config_new"
}

View File

@@ -0,0 +1,387 @@
#!/bin/sh
# Copyright (C) Juewuy
#默认dns
[ -z "$dns_nameserver" ] && dns_nameserver='223.5.5.5'
[ -z "$dns_fallback" ] && dns_fallback="1.1.1.1"
[ -z "$dns_resolver" ] && dns_resolver="223.5.5.5"
#修饰singbox配置文件
parse_singbox_dns() { #dns转换
first_dns=$(echo "$1" | cut -d',' -f1 | cut -d' ' -f1)
type=""
server=""
port=""
case "$first_dns" in
*://*)
type="${first_dns%%://*}"
tmp="${first_dns#*://}"
;;
*)
type="udp"
tmp="$first_dns"
;;
esac
case "$tmp" in
\[*\]*)
server="${tmp%%]*}"
server="${server#[}"
port="${tmp#*\]}"
port="${port#:}"
;;
*)
server="${tmp%%[:/]*}"
port="${tmp#*:}"
[ "$port" = "$tmp" ] && port=""
;;
esac
if [ -z "$port" ]; then
case "$type" in
udp|tcp) port=53 ;;
doh|https) port=443 ;;
dot|tls) port=853 ;;
*) port=53 ;;
esac
fi
# 输出
echo '"type": "'"$type"'", "server": "'"$server"'", "server_port": '"$port"','
}
modify_json() {
#提取配置文件以获得outbounds.json,providers.json及route.json
"$TMPDIR"/CrashCore format -c $core_config >"$TMPDIR"/format.json
echo '{' >"$TMPDIR"/jsons/outbounds.json
echo '{' >"$TMPDIR"/jsons/route.json
cat "$TMPDIR"/format.json | sed -n '/"outbounds":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/outbounds.json
[ "$crashcore" = "singboxr" ] && {
echo '{' >"$TMPDIR"/jsons/providers.json
cat "$TMPDIR"/format.json | sed -n '/^ "providers":/,/^ "[a-z]/p' | sed '$d' >>"$TMPDIR"/jsons/providers.json
}
cat "$TMPDIR"/format.json | sed -n '/"route":/,/^\( "[a-z]\|}\)/p' | sed '$d' >>"$TMPDIR"/jsons/route.json
#生成endpoints.json
[ "$ts_service" = ON ] || [ "$wg_service" = ON ] && {
. "$CRASHDIR"/configs/gateway.cfg
. "$CRASHDIR"/libs/sb_endpoints.sh
}
#生成log.json
cat >"$TMPDIR"/jsons/log.json <<EOF
{ "log": { "level": "info", "timestamp": true } }
EOF
#生成add_hosts.json
if [ "$hosts_opt" != "未启用" ]; then #本机hosts
sys_hosts=/etc/hosts
[ -s /data/etc/custom_hosts ] && sys_hosts=/data/etc/custom_hosts
#NTP劫持
cat >"$TMPDIR"/jsons/add_hosts.json <<EOF
{
"dns": {
"servers": [
{
"type": "hosts",
"tag": "hosts",
"path": [
"$sys_hosts",
"$HOME/.hosts"
],
"predefined": {
"localhost": [
"127.0.0.1",
"::1"
],
"time.android.com": "203.107.6.88",
"time.facebook.com": "203.107.6.88"
}
}
],
"rules": [
{
"ip_accept_any": true,
"server": "hosts"
}
]}
}
EOF
fi
#生成dns.json
[ "$ipv6_dns" != "未开启" ] && strategy='prefer_ipv4' || strategy='ipv4_only'
#获取detour出口
auto_detour=$(grep -E '"type": "urltest"' -A 1 "$TMPDIR"/jsons/outbounds.json | grep '"tag":' | head -n 1 | sed 's/^[[:space:]]*"tag": //;s/,$//')
[ -z "$auto_detour" ] && auto_detour=$(grep -E '"type": "selector"' -A 1 "$TMPDIR"/jsons/outbounds.json | grep '"tag":' | head -n 1 | sed 's/^[[:space:]]*"tag": //;s/,$//')
[ -z "$auto_detour" ] && auto_detour='"DIRECT"'
#根据dns模式生成
[ "$dns_mod" = "redir_host" ] && {
global_dns=dns_proxy
direct_dns='{ "inbound": [ "dns-in" ], "server": "dns_direct" }'
}
[ "$dns_mod" = "fake-ip" ] || [ "$dns_mod" = "mix" ] && {
global_dns=dns_fakeip
fake_ip_filter_domain=$(cat ${CRASHDIR}/configs/fake_ip_filter ${CRASHDIR}/configs/fake_ip_filter.list 2>/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 <<EOF
{
"route": {
"rule_set": [
{
"tag": "cn",
"type": "local",
"path": "./ruleset/cn.srs"
}
]
}
}
EOF
cat >"$TMPDIR"/jsons/dns.json <<EOF
{
"dns": {
"servers": [
{
"tag": "dns_proxy",
$(parse_singbox_dns "$dns_fallback")
"routing_mark": $routing_mark,
"detour": $auto_detour,
"domain_resolver": "dns_resolver"
},
{
"tag": "dns_direct",
$(parse_singbox_dns "$dns_nameserver")
"routing_mark": $routing_mark,
"domain_resolver": "dns_resolver"
},
{
"tag": "dns_fakeip",
"type": "fakeip",
"inet4_range": "28.0.0.0/8",
"inet6_range": "fc00::/16"
},
{
"tag": "dns_resolver",
$(parse_singbox_dns "$dns_resolver")
"routing_mark": $routing_mark
}
],
"rules": [
{ "clash_mode": "Direct", "server": "dns_direct", "strategy": "$strategy" },
{ "domain_suffix": ["services.googleapis.cn"], "server": "dns_fakeip", "strategy": "$strategy", "rewrite_ttl": 1 },
$fake_ip_filter_domain
$fake_ip_filter_suffix
$fake_ip_filter_regex
{ "clash_mode": "Global", "query_type": ["A", "AAAA"], "server": "$global_dns", "strategy": "$strategy", "rewrite_ttl": 1 },
$direct_dns
$proxy_dns
],
"final": "dns_proxy",
"strategy": "$strategy",
"independent_cache": true,
"reverse_mapping": true
}
}
EOF
#生成add_route.json
#域名嗅探配置
[ "$sniffer" = "已启用" ] && sniffer_set='{ "inbound": [ "redirect-in", "tproxy-in", "tun-in" ], "action": "sniff", "timeout": "500ms" },'
[ "advertise_exit_node" = true ] && tailscale_set='{ "inbound": [ "ts-ep" ], "port": 53, "action": "hijack-dns" },'
cat >"$TMPDIR"/jsons/add_route.json <<EOF
{
"route": {
"default_domain_resolver": "dns_resolver",
"default_mark": $routing_mark,
"rules": [
{ "inbound": [ "dns-in" ], "action": "hijack-dns" },
$tailscale_set
$sniffer_set
{ "clash_mode": "Direct" , "outbound": "DIRECT" },
{ "clash_mode": "Global" , "outbound": "GLOBAL" }
]
}
}
EOF
#生成certificate.json
cat >"$TMPDIR"/jsons/certificate.json <<EOF
{
"certificate": {
"store": "mozilla"
}
}
EOF
#生成inbounds.json
[ -n "$authentication" ] && {
username=$(echo $authentication | awk -F ':' '{print $1}') #混合端口账号密码
password=$(echo $authentication | awk -F ':' '{print $2}')
userpass='"users": [{ "username": "'$username'", "password": "'$password'" }], '
}
cat >"$TMPDIR"/jsons/inbounds.json <<EOF
{
"inbounds": [
{
"type": "mixed",
"tag": "mixed-in",
"listen": "::",
$userpass
"listen_port": $mix_port
},
{
"type": "direct",
"tag": "dns-in",
"listen": "::",
"listen_port": $dns_port
},
{
"type": "redirect",
"tag": "redirect-in",
"listen": "::",
"listen_port": $redir_port
},
{
"type": "tproxy",
"tag": "tproxy-in",
"listen": "::",
"listen_port": $tproxy_port
}
]
}
EOF
#inbounds.json添加自定义入站
[ "$vms_service" = ON ] || [ "$sss_service" = ON ] && {
. "$CRASHDIR"/configs/gateway.cfg
. "$CRASHDIR"/libs/sb_inbounds.sh
}
if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ]; then
[ "ipv6_redir" = '已开启' ] && ipv6_address='"fe80::e5c5:2469:d09b:609a/64",'
cat >>"$TMPDIR"/jsons/tun.json <<EOF
{
"inbounds": [
{
"type": "tun",
"tag": "tun-in",
"interface_name": "utun",
"address": [
$ipv6_address
"28.0.0.1/30"
],
"auto_route": false,
"stack": "system"
}
]
}
EOF
fi
#生成add_outbounds.json
grep -qE '"tag": "DIRECT"' "$TMPDIR"/jsons/outbounds.json || add_direct='{ "tag": "DIRECT", "type": "direct" }'
grep -qE '"tag": "REJECT"' "$TMPDIR"/jsons/outbounds.json || add_reject='{ "tag": "REJECT", "type": "block" }'
grep -qE '"tag": "GLOBAL"' "$TMPDIR"/jsons/outbounds.json || {
auto_proxies=$(grep -E '"type": "(selector|urltest)"' -A 1 "$TMPDIR"/jsons/outbounds.json | grep '"tag":' | sed 's/^[[:space:]]*"tag": //;$ s/,$//')
[ -n "$auto_proxies" ] && add_global='{ "tag": "GLOBAL", "type": "selector", "outbounds": ['"$auto_proxies"', "DIRECT"]}'
}
[ -n "$add_direct" -a -n "$add_reject" ] && add_direct="${add_direct},"
[ -n "$add_reject" -a -n "$add_global" ] && add_reject="${add_reject},"
[ -n "$add_direct$add_reject$add_global" ] && cat >"$TMPDIR"/jsons/add_outbounds.json <<EOF
{
"outbounds": [
$add_direct
$add_reject
$add_global
]
}
EOF
#生成experimental.json
cat >"$TMPDIR"/jsons/experimental.json <<EOF
{
"experimental": {
"clash_api": {
"external_controller": "0.0.0.0:$db_port",
"external_ui": "ui",
"external_ui_download_url": "$external_ui_url",
"secret": "$secret",
"default_mode": "Rule"
}
}
}
EOF
#生成自定义规则文件
[ -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 [ "$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
}

View File

@@ -1,94 +0,0 @@
#!/bin/sh
# Copyright (C) Juewuy
CRASHDIR="$(uci get firewall.ShellCrash.path | sed 's/\/misnap_init.sh//')"
profile=/etc/profile
. "$CRASHDIR"/configs/ShellCrash.cfg
autoSSH(){
#自动开启SSH
[ "`uci -c /usr/share/xiaoqiang get xiaoqiang_version.version.CHANNEL`" != 'stable' ] && {
uci -c /usr/share/xiaoqiang set xiaoqiang_version.version.CHANNEL='stable'
uci -c /usr/share/xiaoqiang commit xiaoqiang_version.version
}
[ -z "$(pidof dropbear)" -o -z "$(netstat -ntul | grep :22)" ] && {
sed -i 's/channel=.*/channel="debug"/g' /etc/init.d/dropbear
/etc/init.d/dropbear restart
mi_autoSSH_pwd=$(grep 'mi_autoSSH_pwd=' $CRASHDIR/configs/ShellCrash.cfg | awk -F "=" '{print $2}')
[ -n "$mi_autoSSH_pwd" ] && echo -e "$mi_autoSSH_pwd\n$mi_autoSSH_pwd" | passwd root
}
#配置nvram
[ "$(nvram get ssh_en)" = 0 ] && nvram set ssh_en=1
[ "$(nvram get telnet_en)" = 0 ] && nvram set telnet_en=1
nvram commit &> /dev/null
#备份还原SSH秘钥
[ -f $CRASHDIR/configs/dropbear_rsa_host_key ] && ln -sf $CRASHDIR/configs/dropbear_rsa_host_key /etc/dropbear/dropbear_rsa_host_key
[ -f $CRASHDIR/configs/authorized_keys ] && ln -sf $CRASHDIR/configs/authorized_keys /etc/dropbear/authorized_keys
}
tunfix(){
ko_dir=$(modinfo ip_tables | grep -Eo '/lib/modules.*/ip_tables.ko' | sed 's|/ip_tables.ko||' )
#在/tmp创建并挂载overlay
mkdir -p /tmp/overlay
mkdir -p /tmp/overlay/upper
mkdir -p /tmp/overlay/work
mount -o noatime,lowerdir=${ko_dir},upperdir=/tmp/overlay/upper,workdir=/tmp/overlay/work -t overlay "overlay_mods_only" ${ko_dir}
#将tun.ko链接到lib
ln -sf $CRASHDIR/tools/tun.ko ${ko_dir}/tun.ko || $CRASHDIR/start.sh loggger "小米Tun模块修复失败"
}
tproxyfix(){
sed -i 's/sysctl -w net.bridge.bridge-nf-call-ip/#sysctl -w net.bridge.bridge-nf-call-ip/g' /etc/init.d/qca-nss-ecm
sysctl -w net.bridge.bridge-nf-call-iptables=0
sysctl -w net.bridge.bridge-nf-call-ip6tables=0
}
auto_clean(){
#自动清理升级备份文件夹
rm -rf /data/etc_bak
#自动清理被写入闪存的系统日志并禁止服务
/etc/init.d/stat_points stop 2>/dev/null
/etc/init.d/stat_points disable 2>/dev/null
sed -i '\#/logrotate#{ /^[[:space:]]*#/!s/^/#ShellCrash自动注释 / }' /etc/crontabs/root
rm -rf /data/usr/log
}
init(){
#等待启动完成
while ! ip a| grep -q lan; do
sleep 10
done
sleep 20
#初始化环境变量
[ -z "$my_alias" ] && my_alias=crash
sed -i "/ShellCrash\/menu.sh/"d "$profile"
echo "alias ${my_alias}=\"sh $CRASHDIR/menu.sh\"" >>"$profile"
sed -i "/export CRASHDIR/d" "$profile"
echo "export CRASHDIR=\"$CRASHDIR\"" >>"$profile"
autoSSH #软固化功能
auto_clean #自动清理
#设置init.d服务
cp -f $CRASHDIR/shellcrash.procd /etc/init.d/shellcrash
chmod 755 /etc/init.d/shellcrash
#启动服务
if [ ! -f $CRASHDIR/.dis_startup ]; then
#AX6S/AX6000修复tun功能
[ -s $CRASHDIR/tools/tun.ko ] && tunfix
#小米7000/小米万兆修复tproxy
[ -f /etc/init.d/qca-nss-ecm ] && [ -n "$(grep 'redir_mod=Tproxy' $CRASHDIR/configs/ShellCrash.cfg )" ] && tproxyfix
#自动覆盖根证书文件
[ -s $CRASHDIR/tools/ca-certificates.crt ] && cp -f $CRASHDIR/tools/ca-certificates.crt /etc/ssl/certs/ca-certificates.crt
#启动服务
$CRASHDIR/start.sh start
/etc/init.d/shellcrash enable
fi
}
case "$1" in
tunfix) tunfix ;;
tproxyfix) tproxyfix ;;
auto_clean) auto_clean ;;
init) init ;;
*)
if [ -z $(pidof CrashCore) ];then
init &
fi
;;
esac

View File

@@ -0,0 +1,12 @@
if [ "$start_old" != "已开启" ] && ckcmd journalctl; then
journalctl -u shellcrash >"$TMPDIR"/core_test.log
else
PID=$(pidof CrashCore) && [ -n "$PID" ] && kill -9 "$PID" >/dev/null 2>&1
${COMMAND} >"$TMPDIR"/core_test.log 2>&1 &
sleep 2
kill $! >/dev/null 2>&1
fi
error=$(cat $TMPDIR/core_test.log | grep -iEo 'error.*=.*|.*ERROR.*|.*FATAL.*')
logger "服务启动失败!请查看报错信息!详细信息请查看$TMPDIR/core_test.log" 33
logger "$error" 31