ShellCrash 基本教程

ShellCrash 是一个科学上网工具,类似于 Passwall、OpenClash 等,但是区别在于,从名字可以看出,它是基于 Shell 脚本实现的,并没有图形界面。

如果你折腾够了 Passwall、OpenClash 等插件,或者觉得它们用不明白,或者觉得不满足你的需求,或许可以试试 ShellCrash。

本教程所使用的环境:

  • 光猫:桥接
  • 软路由硬件:FriendlyARM NanoPi R5C
  • 系统:ImmortalWrt 23.05.3 (防火墙为 nftables)
  • ShellCrash 版本:1.9.1beta13
  • 内核:sing-box
  • 节点类型:自建
  • 网络:IPv4 + IPv6

本教程更确切地说是针对自建节点 + 手写配置文件的用户,其他环境以及订阅用户,由于本人没有尝试,不多做说明。

安装

ImmortalWrt 初始化设置

在设置好 LAN 口的 IP 地址以及在 WAN 口进行 PPPoE 拨号之后,由于 ImmortalWrt 本身比较精简,需要在软件包中安装一些必要依赖:

  • curl
  • openssh-sftp-server
  • kmod-nft-tproxy

ShellCrash 安装

假设你的路由器 IP 地址为 192.168.50.1,使用 SSH 登录到路由器,方法如下:

ssh root@192.168.50.1

然后执行 官方 安装命令:

export url='https://fastly.jsdelivr.net/gh/juewuy/ShellCrash@master' && sh -c "$(curl -kfsSl $url/install.sh)" && source /etc/profile &> /dev/null

选择 1 公测版,选择 1 安装在 /etc 目录,选择 1 确认。

安装完成之后,运行 crash 命令,选择 1 路由设备配置局域网透明代理,选择 0 不启用推荐的自动任务配置,选择 0 不导入配置文件,选择 0 不立即启动服务,此时会进入 ShellCrash 的主菜单,选择 0 退出脚本。

在启动之前,我们需要准备好 sing-box 内核使用的配置文件。

配置

在你的电脑上新建一个 config.json 的文件,使用 vscode 等软件打开。由于 ShellCrash 会自动追加一些默认配置,所以事实上并不需要编写很多内容,基本上只需要写好 routeoutbounds 即可。以下配置仅供参考:

{
  "outbounds": [
    // 此处节点仅供参考,实际使用时请替换为自己的节点
    {
      "tag": "proxy",
      "type": "trojan",
      "server": "example.com",
      "server_port": 443,
      "password": "xxx",
      "tls": {
        "enabled": true,
        "server_name": "example.com"
      }
    }
  ],
  "route": {
    "rule_set": [
      {
        "tag": "geosite-private",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/private.srs",
        "download_detour": "DIRECT" // 注意这里一定要写为 DIRECT 而不是 direct,DIRECT 是 ShellCrash 的默认直连出站标签
      },
      {
        "tag": "geosite-google",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/google.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geosite-apple",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/apple.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geosite-icloud",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/icloud.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geosite-microsoft@cn",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/microsoft@cn.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geosite-cn",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/cn.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geosite-geolocation-!cn",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geosite/geolocation-!cn.srs",
        "download_detour": "DIRECT"
      },
      {
        "tag": "geoip-cn",
        "type": "remote",
        "format": "binary",
        "url": "https://testingcf.jsdelivr.net/gh/MetaCubeX/meta-rules-dat@sing/geo/geoip/cn.srs",
        "download_detour": "DIRECT"
      }
    ],
    "rules": [
      {
        "ip_is_private": true,
        "outbound": "DIRECT"
      },
      {
        "rule_set": "geosite-private",
        "outbound": "DIRECT"
      },
      {
        "rule_set": ["geosite-icloud"],
        "outbound": "DIRECT"
      },
      {
        "rule_set": ["geosite-apple"],
        "outbound": "DIRECT"
      },
      {
        "rule_set": ["geosite-microsoft@cn"],
        "outbound": "DIRECT"
      },
      {
        "rule_set": ["geosite-google"],
        "outbound": "proxy"
      },
      {
        "rule_set": "geosite-geolocation-!cn",
        "outbound": "proxy"
      },
      {
        "rule_set": ["geosite-cn"],
        "outbound": "DIRECT"
      },
      {
        "rule_set": "geoip-cn",
        "outbound": "DIRECT"
      }
    ],
    "final": "proxy"
  }
}

配置文件写好之后,你需要将其上传到路由器上,方法有很多,比如使用 scp 命令:

scp config.json root@192.168.50.1:/tmp/

运行 ShellCrash

登录到路由器,运行 crash 命令。

安装 sing-box 内核

选择 9 更新/卸载 - 2 切换内核文件 - 2 SingBox,此时 ShellCrash 会自动下载内核文件并安装,选择 0 不保留相关数据库文件。

安装本地 Dashboard 面板

在保持 9 更新/卸载 的菜单中,选择 4 安装本地Dashboard面板 - 2 安装Yacd-Meta魔改面板,安装完成后选择 0 返回上级菜单,此时会提示 是否加载为singbox的配置文件,选择 1 加载。

配置 ShellCrash 运行

在 crash 主菜单中,选择 2 内核功能设置

  • 1 切换防火墙运行模式 选择 3 Tproxy模式
  • 2 切换DNS运行模式 选择 3 mix混合模式
  • 7 屏蔽QUIC流量 开启

在 crash 主菜单中,选择 7 内核进阶设置 - 4 启用域名嗅探 开启。

重新回到 crash 主菜单,选择 1 启动/重启服务,ShellCrash 在下载好所需依赖之后,将会自动启动。此时你应该就可以正常的科学上网了。打开 http://192.168.50.1:9999/ui/#/ 查看 Dashboard 面板。

进阶配置

自定义 DNS

使用 sing-box 内核时,ShellCrash 的 DNS 模式只有两种:fake-ip模式mix混合模式,如果你不想使用 fake-ip,或者这两种模式的默认配置无法满足你的需求,可以完全自定义 DNS 配置。

在电脑上新建一个文件 dns.json,内容如下:

{
  "dns": {
    "servers": [
      {
        "tag": "dns_proxy",
        "address": "https://1.1.1.1/dns-query",
        "detour": "proxy"
      },
      {
        "tag": "dns_direct",
        "address": "https://223.5.5.5/dns-query",
        "detour": "DIRECT"
      }
    ],
    "rules": [
      { "outbound": ["any"], "server": "dns_direct" },
      {
        "rule_set": "geosite-private",
        "server": "dns_direct"
      },
      {
        "rule_set": ["geosite-icloud", "geosite-apple", "geosite-microsoft@cn"],
        "server": "dns_direct"
      },
      {
        "rule_set": ["geosite-cn"],
        "server": "dns_direct"
      },
      {
        "type": "logical",
        "mode": "and",
        "rules": [
          {
            "rule_set": "geosite-geolocation-!cn",
            "invert": true
          },
          {
            "rule_set": "geoip-cn"
          }
        ],
        "server": "dns_proxy",
        "client_subnet": "1.0.1.0"
      }
    ],
    "final": "dns_proxy",
    "independent_cache": true,
    "reverse_mapping": true
  }
}

以上配置仅供参考,编辑完成之后,上传到路由器上:

scp dns.json root@192.168.50.1:/etc/ShellCrash/jsons/

在路由器运行 crash 命令,选择 1 启动/重启服务 即可生效,此时 ShellCrash 的 DNS 设置将会完全失效。

DNS 详细配置语法请参考 sing-box 官方文档:https://sing-box.sagernet.org/zh/configuration/dns/

自定义路由

自定义规则集配置

如果你对上面的 rule_setrules 不满意,可以自定义规则集配置,你可以在 这里 找到更多的规则集文件,然后参照上面的配置文件进行修改。

自定义域名和 IP

如果你有一些自己的域名或者 IP,想要直连或者代理,可以在 route 中添加自定义规则,例如:

{
  "rules": [
    {
      "domain_suffix": ["yourdomain.com"],
      "outbound": "DIRECT"
    },
    {
      "ip_cidr": ["1.2.3.4/32"],
      "outbound": "proxy"
    }
  ]
}

自定义本地规则集

如果你有很多的域名或 IP,可以创建一个本地的规则集文件,例如 my_rule_set.json

{
  "version": 1,
  "rules": [
    {
      "domain_suffix": ["yourdomain1.com", "yourdomain2.com"]
    },
    {
      "ip_cidr": ["1.2.3.4/32", "2.3.4.5/32"]
    }
  ]
}

在路由器 /etc/ShellCrash 目录下新建一个目录 rules,将 my_rule_set.json 上传到这个目录:

scp my_rule_set.json root@192.168.50.1:/etc/ShellCrash/rules/

编辑 config.json 以使用 my_rule_set.json

{
  "route": {
    "rule_set": [
      // 其他规则集...
      {
        "type": "local",
        "tag": "my_rule_set",
        "format": "source",
        "path": "./rules/my_rule_set.json"
      }
    ],
    "rules": [
      {
        "rule_set": "my_rule_set",
        "outbound": "DIRECT"
      }
      // 其他路由规则...
    ]
  }
}

重新上传 config.json 到路由器,然后在路由器运行 crash 命令,选择 1 启动/重启服务 即可生效。

规则详细配置语法请参考 sing-box 官方文档:https://sing-box.sagernet.org/zh/configuration/route/

CN_IP 绕过内核

对于国内网站和 IP,你可以启用 CN_IP绕过内核 功能使得这些流量不经过内核,直接走原生路由,这样可以减轻内核的负担,提高性能。设置方法如下:

在路由器运行 crash 命令,选择 2 内核功能设置 - 8 CN_IP绕过内核。如果你的网络环境有 IPv6,还需要 2 内核功能设置 - 1 切换防火墙运行模式 - 9 ipv6设置 - 3 CNV6绕过内核

重启 ShellCrash 之后,在 /etc/ShellCrash 目录会发现有 cn_ip.txtcn_ipv6.txt 两个文件,ShellCrash 会将这两个文件中的 IP 地址写入到防火墙中,使得这些 IP 地址不经过内核。

自定义定时任务

由于 cn_ip.txtcn_ipv6.txt 的内容会经常更新,你可以使用 ShellCrash 的定时任务功能定时更新这两个文件,推荐设置如下:

选择 5 配置自动任务 - 1 添加自动任务 - 10 自动更新数据库文件 - 5 服务启动前执行,然后选择 1 添加自动任务 - 3 重启clash服务 - 1 定时任务每周执行,输入你想执行的日期和时间,比如每周日早上 7 点。

添加完成之后,ShellCrash 就可以在你设置的时间自动重启服务,并且在启动之前更新数据库文件。

自定义日志设置

当你打开 http://192.168.50.1:9999/ui/#/logs 查看日志时,你会发现日志非常多,包括了很多不必要的信息,你可以自定义日志设置,只显示你关心的信息。

在电脑上新建一个文件 log.json,内容如下:

{
  "log": {
    "level": "warn",
    "timestamp": true
  }
}

编辑完成之后,上传到路由器上:

scp log.json root@192.168.50.1:/etc/ShellCrash/jsons/

在路由器运行 crash 命令,选择 1 启动/重启服务 即可生效。此时,只有日志级别为 warnerror 的日志会显示。

使用最新内核

ShellCrash 默认的 sing-box 内核版本有时候可能不是最新的,你可以这样来使用最新的内核:

在路由器运行 crash 命令,选择 9 更新/卸载 - 2 切换内核文件 - 5 自定义内核 - 4 SagerNet/sing-box@release版本内核,选择你想安装的版本即可。

使用 alpha 内核

如果你想尝试开发中的 alpha 版本 sing-box 内核,有两种方法:

通过 ShellCrash

在路由器运行 crash 命令,选择 9 更新/卸载 - 2 切换内核文件 - 5 自定义内核 - a 自定义内核链接,浏览器打开 sing-box releases 页面,找到你需要的 alpha 版本内核,复制链接,粘贴即可。

手动安装

sing-box releases 页面下载你需要的内核,解压缩,将 sing-box 文件手动上传到路由器,方法如下:

scp sing-box root@192.168.50.1:/tmp/

然后在路由器运行 crash 命令,会提示发现可用的新内核文件,按照提示选择即可。

查看 ShellCrash 最终设置

前面提到 ShellCrash 会自动追加一些默认配置,如果你想查看最终的配置文件,可以在路由器上进入 /tmp/ShellCrash/jsons 目录,查看 ShellCrash 运行时使用的最终 sing-box 配置。

或者你可以将这些配置文件拉取到本地电脑上,使用 vscode 等软件打开:

scp root@192.168.50.1:'/tmp/ShellCrash/jsons/*.json' ./

这个命令的意思是将 /tmp/ShellCrash/jsons 目录下的所有 json 文件拉取到当前目录。

理解 ShellCrash

ShellCrash 本质上就是一个用来生成防火墙规则以及内核配置文件的工具,不同的 ShellCrash 选项会生成不同的配置文件,sing-box 基于最终的配置文件来运行。

你可以通过尝试各个 ShellCrash 选项,然后查看 /tmp/ShellCrash/jsons 目录中的文件变更以及 nftables 规则变更以理解 ShellCrash 的各个选项到底做了什么。

结语

ShellCrash 是一个非常强大的科学上网工具,它的配置非常灵活,可以满足大部分用户的需求。但是由于它是基于 Shell 脚本实现的,所以配置起来可能会有一些困难,需要一定的技术基础。

以上给出的配置文件仅供参考,你可以根据自己的需求进行修改,并且多尝试 ShellCrash 的其他功能,在掌握了 ShellCrash 的基本使用之后,更多的精力应该放在阅读 sing-box 官方文档上,这样你才能更好地打造一个适合自己的科学上网环境。

希望这篇文章能够帮助到你,即使你的环境与我有所区别,也能够参考到一些内容。