#!/bin/sh # Copyright (C) Juewuy #修饰clash配置文件 modify_yaml() { ##########需要变更的配置########### [ "$ipv6_dns" != "未开启" ] && dns_v6='true' || dns_v6='false' external="external-controller: 0.0.0.0:$db_port" if [ "$redir_mod" = "混合模式" -o "$redir_mod" = "Tun模式" ]; then [ "$crashcore" = 'meta' ] && tun_meta=', device: utun, auto-route: false, auto-detect-interface: false' tun="tun: {enable: true, stack: system$tun_meta}" else tun='tun: {enable: false}' fi exper='experimental: {ignore-resolve-fail: true, interface-name: en0}' #Meta内核专属配置 [ "$crashcore" = 'meta' ] && { [ "$redir_mod" != "纯净模式" ] && [ -z "$(grep 'PROCESS' "$CRASHDIR"/yamls/*.yaml)" ] && find_process='find-process-mode: "off"' } #dns配置 [ -z "$(cat "$CRASHDIR"/yamls/user.yaml 2>/dev/null | grep '^dns:')" ] && { [ "$crashcore" != meta ] && dns_resolver='223.5.5.5' cat >"$TMPDIR"/dns.yaml </dev/null | grep -v '#' | sed "s/^/ - '/" | sed "s/$/'/" >>"$TMPDIR"/dns.yaml else echo " - '+.*'" >>"$TMPDIR"/dns.yaml #使用fake-ip模拟redir_host fi #mix模式fakeip绕过cn [ "$dns_mod" = "mix" ] && echo ' - "rule-set:cn"' >>"$TMPDIR"/dns.yaml #mix模式和route模式插入分流设置 if [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ]; then [ "$dns_protect" != "OFF" ] && dns_final="$dns_fallback" || dns_final="$dns_nameserver" cat >>"$TMPDIR"/dns.yaml <>"$TMPDIR"/dns.yaml <"$TMPDIR"/set.yaml </dev/null)" ]; then #NTP劫持 cat >"$TMPDIR"/hosts.yaml <>"$TMPDIR"/hosts.yaml else #加载本机hosts sys_hosts=/etc/hosts [ -f /data/etc/custom_hosts ] && sys_hosts=/data/etc/custom_hosts while read line; do [ -n "$(echo "$line" | grep -oE "([0-9]{1,3}[\.]){3}")" ] && [ -z "$(echo "$line" | grep -oE '^#')" ] && hosts_ip=$(echo $line | awk '{print $1}') && hosts_domain=$(echo $line | awk '{print $2}') && [ -z "$(cat "$TMPDIR"/hosts.yaml | grep -oE "$hosts_domain")" ] && echo " '$hosts_domain': $hosts_ip" >>"$TMPDIR"/hosts.yaml done <$sys_hosts fi fi #分割配置文件 yaml_char='proxies proxy-groups proxy-providers rules rule-providers sub-rules listeners' for char in $yaml_char; do sed -n "/^$char:/,/^[a-z]/ { /^[a-z]/d; p; }" $core_config >"$TMPDIR"/${char}.yaml done #跳过本地tls证书验证 [ "$skip_cert" != "未开启" ] && sed -i 's/skip-cert-verify: false/skip-cert-verify: true/' "$TMPDIR"/proxies.yaml || sed -i 's/skip-cert-verify: true/skip-cert-verify: false/' "$TMPDIR"/proxies.yaml #插入自定义策略组 sed -i "/#自定义策略组开始/,/#自定义策略组结束/d" "$TMPDIR"/proxy-groups.yaml sed -i "/#自定义策略组/d" "$TMPDIR"/proxy-groups.yaml [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxy-groups.yaml 2>/dev/null)" ] && { #获取空格数 space_name=$(grep -aE '^ *- \{?name: ' "$TMPDIR"/proxy-groups.yaml | head -n 1 | grep -oE '^ *') space_proxy="$space_name " #合并自定义策略组到proxy-groups.yaml cat "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | sed "s/#.*//g" | sed '1i\ #自定义策略组开始' | sed '$a\ #自定义策略组结束' | sed "s/^ */${space_name} /g" | sed "s/^ *- /${space_proxy}- /g" | sed "s/^ *- name: /${space_name}- name: /g" | sed "s/^ *- {name: /${space_name}- {name: /g" >"$TMPDIR"/proxy-groups_add.yaml cat "$TMPDIR"/proxy-groups.yaml >>"$TMPDIR"/proxy-groups_add.yaml mv -f "$TMPDIR"/proxy-groups_add.yaml "$TMPDIR"/proxy-groups.yaml oldIFS="$IFS" grep "\- name: " "$CRASHDIR"/yamls/proxy-groups.yaml | sed "/^#/d" | while read line; do #将自定义策略组插入现有的proxy-group new_group=$(echo $line | grep -Eo '^ *- name:.*#' | cut -d'#' -f1 | sed 's/.*name: //g') proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") IFS="#" for name in $proxy_groups; do line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 [ -n "$line_a" ] && { line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 line_c=$((line_a + line_b - 1)) #计算需要插入的行号 space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${new_group} #自定义策略组" "$TMPDIR"/proxy-groups.yaml } done IFS="$oldIFS" done } #插入自定义代理 sed -i "/#自定义代理/d" "$TMPDIR"/proxies.yaml sed -i "/#自定义代理/d" "$TMPDIR"/proxy-groups.yaml [ -n "$(grep -Ev '^#' "$CRASHDIR"/yamls/proxies.yaml 2>/dev/null)" ] && { space_proxy=$(cat "$TMPDIR"/proxies.yaml | grep -aE '^ *- ' | head -n 1 | grep -oE '^ *') #获取空格数 cat "$CRASHDIR"/yamls/proxies.yaml | sed "s/^ *- /${space_proxy}- /g" | sed "/^#/d" | sed "/^ *$/d" | sed 's/#.*/ #自定义代理/g' >>"$TMPDIR"/proxies.yaml #插入节点 oldIFS="$IFS" cat "$CRASHDIR"/yamls/proxies.yaml | sed "/^#/d" | while read line; do #将节点插入proxy-group proxy_name=$(echo $line | grep -Eo 'name: .+, ' | cut -d',' -f1 | sed 's/name: //g') proxy_groups=$(echo $line | grep -Eo '#.*' | sed "s/#//") IFS="#" for name in $proxy_groups; do line_a=$(grep -n "\- name: $name" "$TMPDIR"/proxy-groups.yaml | head -n 1 | awk -F: '{print $1}') #获取group行号 [ -n "$line_a" ] && { line_b=$(grep -A 8 "\- name: $name" "$TMPDIR"/proxy-groups.yaml | grep -n "proxies:$" | head -n 1 | awk -F: '{print $1}') #获取proxies行号 line_c=$((line_a + line_b - 1)) #计算需要插入的行号 space=$(sed -n "$((line_c + 1))p" "$TMPDIR"/proxy-groups.yaml | grep -oE '^ *') #获取空格数 [ "$line_c" -gt 2 ] && sed -i "${line_c}a\\${space}- ${proxy_name} #自定义代理" "$TMPDIR"/proxy-groups.yaml } done IFS="$oldIFS" done } #添加自定义入站 [ "$vms_service" = ON ] || [ "$sss_service" = ON ] && { . "$CRASHDIR"/configs/gateway.cfg . "$CRASHDIR"/libs/meta_listeners.sh } #节点绕过功能支持 sed -i "/#节点绕过/d" "$TMPDIR"/rules.yaml [ "$proxies_bypass" = "已启用" ] && { cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | awk '!a[$0]++' | sed 's/^/\ -\ IP-CIDR,/g' | sed 's|$|/32,DIRECT,no-resolve #节点绕过|g' >>"$TMPDIR"/proxies_bypass cat "$TMPDIR"/proxies.yaml | sed '/^proxy-/,$d' | sed '/^rule-/,$d' | grep -v '^\s*#' | grep -vE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | grep -oE '[a-zA-Z0-9][-a-zA-Z0-9]{0,62}(\.[a-zA-Z0-9][-a-zA-Z0-9]{0,62})+\.?' | awk '!a[$0]++' | sed 's/^/\ -\ DOMAIN,/g' | sed 's/$/,DIRECT #节点绕过/g' >>"$TMPDIR"/proxies_bypass cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/proxies_bypass mv -f "$TMPDIR"/proxies_bypass "$TMPDIR"/rules.yaml } #插入自定义规则 sed -i "/#自定义规则/d" "$TMPDIR"/rules.yaml [ -s "$CRASHDIR"/yamls/rules.yaml ] && { cat "$CRASHDIR"/yamls/rules.yaml | sed "/^#/d" | sed '$a\' | sed 's/$/ #自定义规则/g' >"$TMPDIR"/rules.add cat "$TMPDIR"/rules.yaml >>"$TMPDIR"/rules.add mv -f "$TMPDIR"/rules.add "$TMPDIR"/rules.yaml } #mix和route模式生成rule-providers [ "$dns_mod" = "mix" ] || [ "$dns_mod" = "route" ] && ! grep -Eq '^[[:space:]]*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 unified-delay; 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 }