X-UI的手动安装教程，解救自动安装失败的VPS
X-UI是一款非常优秀的科学工具，关于X-UI的特点、自动安装和使用教程，可以查看本站之前的文章：3x-ui安装指南+搭建reality+申请ssl证书。很多网友反馈采用自动脚本安装会失败，包括检测VPS内核、系统识别等等各种原因，其实github自动脚本install.sh中已经有了安装过程，今天就基于该脚本的解读，介绍下如何手动安装X-UI脚本：1 用SSH软件登录你的VPS2 打开/usr/local目录cd /usr/local/3 下载对应系统的压缩包wget -N https://github.com/MHSanaei/3x-ui/releases/download/v2.5.3/x-ui-linux-amd64.tar.gz4 解压，正常解压会产生一个x-ui的文件夹tar zxvf x-ui-linux-amd64.tar.gz5 打开上一步解压产生的x-ui文件夹，查看目录下的文件是否解压正常cd x-ui ls -a6 变更x-ui程序的权限chmod +x x-ui7 安装x-uibash ./x-ui.sh输入上述命令后，正常会弹出3x-ui的安装界面，选择1就是安装，如果安装过可以输入10查看目前安装的信息，记住安装的信息，然后通过浏览器登录，地址为 http://ip地址:端口号/面板路径，用户名和密码见快捷键10提供的当前配置信息：╔────────────────────────────────────────────────╗ │ 3X-UI Panel Management Script │ │ 0. Exit Script │ │────────────────────────────────────────────────│ │ 1. Install │ │ 2. Update │ │ 3. Update Menu │ │ 4. Legacy Version │ │ 5. Uninstall │ │────────────────────────────────────────────────│ │ 6. Reset Username & Password & Secret Token │ │ 7. Reset Web Base Path │ │ 8. Reset Settings │ │ 9. Change Port │ │ 10. View Current Settings │ │────────────────────────────────────────────────│ │ 11. Start │ │ 12. Stop │ │ 13. Restart │ │ 14. Check Status │ │ 15. Logs Management │ │────────────────────────────────────────────────│ │ 16. Enable Autostart │ │ 17. Disable Autostart │ │────────────────────────────────────────────────│ │ 18. SSL Certificate Management │ │ 19. Cloudflare SSL Certificate │ │ 20. IP Limit Management │ │ 21. Firewall Management │ │ 22. SSH Port Forwarding Management │ │────────────────────────────────────────────────│ │ 23. Enable BBR │ │ 24. Update Geo Files │ │ 25. Speedtest by Ookla │ ╚────────────────────────────────────────────────╝ Panel state: Stop Start automatically: Yes xray state: Stop Please enter your selection [0-25]: 18 激活x-ui的Servicecp -f x-ui.service /etc/systemd/system/ systemctl daemon-reload systemctl enable x-ui逐行输入9 启动x-ui Servicesystemctl start x-ui正常这个时候就可以正常使用了10 其他快捷命令systemctl stop x-ui systemctl restart x-ui systemctl status x-ui参考源程序#!/bin/bash red='\033[0;31m' green='\033[0;32m' blue='\033[0;34m' yellow='\033[0;33m' plain='\033[0m' cur_dir=$(pwd) # check root [[ $EUID -ne 0 ]] && echo -e "${red}Fatal error: ${plain} Please run this script with root privilege \n " && exit 1 # Check OS and set release variable if [[ -f /etc/os-release ]]; then source /etc/os-release release=$ID elif [[ -f /usr/lib/os-release ]]; then source /usr/lib/os-release release=$ID else echo "Failed to check the system OS, please contact the author!" >&2 exit 1 fi echo "The OS release is: $release" arch() { case "$(uname -m)" in x86_64 | x64 | amd64) echo 'amd64' ;; i*86 | x86) echo '386' ;; armv8* | armv8 | arm64 | aarch64) echo 'arm64' ;; armv7* | armv7 | arm) echo 'armv7' ;; armv6* | armv6) echo 'armv6' ;; armv5* | armv5) echo 'armv5' ;; s390x) echo 's390x' ;; *) echo -e "${green}Unsupported CPU architecture! ${plain}" && rm -f install.sh && exit 1 ;; esac } echo "arch: $(arch)" os_version="" os_version=$(grep "^VERSION_ID" /etc/os-release | cut -d '=' -f2 | tr -d '"' | tr -d '.') if [[ "${release}" == "arch" ]]; then echo "Your OS is Arch Linux" elif [[ "${release}" == "parch" ]]; then echo "Your OS is Parch Linux" elif [[ "${release}" == "manjaro" ]]; then echo "Your OS is Manjaro" elif [[ "${release}" == "armbian" ]]; then echo "Your OS is Armbian" elif [[ "${release}" == "alpine" ]]; then echo "Your OS is Alpine Linux" elif [[ "${release}" == "opensuse-tumbleweed" ]]; then echo "Your OS is OpenSUSE Tumbleweed" elif [[ "${release}" == "openEuler" ]]; then if [[ ${os_version} -lt 2203 ]]; then echo -e "${red} Please use OpenEuler 22.03 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "centos" ]]; then if [[ ${os_version} -lt 8 ]]; then echo -e "${red} Please use CentOS 8 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "ubuntu" ]]; then if [[ ${os_version} -lt 2004 ]]; then echo -e "${red} Please use Ubuntu 20 or higher version!${plain}\n" && exit 1 fi elif [[ "${release}" == "fedora" ]]; then if [[ ${os_version} -lt 36 ]]; then echo -e "${red} Please use Fedora 36 or higher version!${plain}\n" && exit 1 fi elif [[ "${release}" == "amzn" ]]; then if [[ ${os_version} != "2023" ]]; then echo -e "${red} Please use Amazon Linux 2023!${plain}\n" && exit 1 fi elif [[ "${release}" == "debian" ]]; then if [[ ${os_version} -lt 11 ]]; then echo -e "${red} Please use Debian 11 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "almalinux" ]]; then if [[ ${os_version} -lt 80 ]]; then echo -e "${red} Please use AlmaLinux 8.0 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "rocky" ]]; then if [[ ${os_version} -lt 8 ]]; then echo -e "${red} Please use Rocky Linux 8 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "ol" ]]; then if [[ ${os_version} -lt 8 ]]; then echo -e "${red} Please use Oracle Linux 8 or higher ${plain}\n" && exit 1 fi elif [[ "${release}" == "virtuozzo" ]]; then if [[ ${os_version} -lt 8 ]]; then echo -e "${red} Please use Virtuozzo Linux 8 or higher ${plain}\n" && exit 1 fi else echo -e "${red}Your operating system is not supported by this script.${plain}\n" echo "Please ensure you are using one of the following supported operating systems:" echo "- Ubuntu 20.04+" echo "- Debian 11+" echo "- CentOS 8+" echo "- OpenEuler 22.03+" echo "- Fedora 36+" echo "- Arch Linux" echo "- Parch Linux" echo "- Manjaro" echo "- Armbian" echo "- AlmaLinux 8.0+" echo "- Rocky Linux 8+" echo "- Oracle Linux 8+" echo "- OpenSUSE Tumbleweed" echo "- Amazon Linux 2023" echo "- Virtuozzo Linux 8+" exit 1 fi install_base() { case "${release}" in ubuntu | debian | armbian) apt-get update && apt-get install -y -q wget curl tar tzdata ;; centos | almalinux | rocky | ol) yum -y update && yum install -y -q wget curl tar tzdata ;; fedora | amzn | virtuozzo) dnf -y update && dnf install -y -q wget curl tar tzdata ;; arch | manjaro | parch) pacman -Syu && pacman -Syu --noconfirm wget curl tar tzdata ;; opensuse-tumbleweed) zypper refresh && zypper -q install -y wget curl tar timezone ;; *) apt-get update && apt install -y -q wget curl tar tzdata ;; esac } gen_random_string() { local length="$1" local random_string=$(LC_ALL=C tr -dc 'a-zA-Z0-9' </dev/urandom | fold -w "$length" | head -n 1) echo "$random_string" } config_after_install() { local existing_username=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'username: .+' | awk '{print $2}') local existing_password=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'password: .+' | awk '{print $2}') local existing_webBasePath=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'webBasePath: .+' | awk '{print $2}') local existing_port=$(/usr/local/x-ui/x-ui setting -show true | grep -Eo 'port: .+' | awk '{print $2}') local server_ip=$(curl -s https://api.ipify.org) if [[ ${#existing_webBasePath} -lt 4 ]]; then if [[ "$existing_username" == "admin" && "$existing_password" == "admin" ]]; then local config_webBasePath=$(gen_random_string 15) local config_username=$(gen_random_string 10) local config_password=$(gen_random_string 10) read -p "Would you like to customize the Panel Port settings? (If not, a random port will be applied) [y/n]: " config_confirm if [[ "${config_confirm}" == "y" || "${config_confirm}" == "Y" ]]; then read -p "Please set up the panel port: " config_port echo -e "${yellow}Your Panel Port is: ${config_port}${plain}" else local config_port=$(shuf -i 1024-62000 -n 1) echo -e "${yellow}Generated random port: ${config_port}${plain}" fi /usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" -port "${config_port}" -webBasePath "${config_webBasePath}" echo -e "This is a fresh installation, generating random login info for security concerns:" echo -e "###############################################" echo -e "${green}Username: ${config_username}${plain}" echo -e "${green}Password: ${config_password}${plain}" echo -e "${green}Port: ${config_port}${plain}" echo -e "${green}WebBasePath: ${config_webBasePath}${plain}" echo -e "${green}Access URL: http://${server_ip}:${config_port}/${config_webBasePath}${plain}" echo -e "###############################################" echo -e "${yellow}If you forgot your login info, you can type 'x-ui settings' to check${plain}" else local config_webBasePath=$(gen_random_string 15) echo -e "${yellow}WebBasePath is missing or too short. Generating a new one...${plain}" /usr/local/x-ui/x-ui setting -webBasePath "${config_webBasePath}" echo -e "${green}New WebBasePath: ${config_webBasePath}${plain}" echo -e "${green}Access URL: http://${server_ip}:${existing_port}/${config_webBasePath}${plain}" fi else if [[ "$existing_username" == "admin" && "$existing_password" == "admin" ]]; then local config_username=$(gen_random_string 10) local config_password=$(gen_random_string 10) echo -e "${yellow}Default credentials detected. Security update required...${plain}" /usr/local/x-ui/x-ui setting -username "${config_username}" -password "${config_password}" echo -e "Generated new random login credentials:" echo -e "###############################################" echo -e "${green}Username: ${config_username}${plain}" echo -e "${green}Password: ${config_password}${plain}" echo -e "###############################################" echo -e "${yellow}If you forgot your login info, you can type 'x-ui settings' to check${plain}" else echo -e "${green}Username, Password, and WebBasePath are properly set. Exiting...${plain}" fi fi /usr/local/x-ui/x-ui migrate } install_x-ui() { cd /usr/local/ if [ $# == 0 ]; then tag_version=$(curl -Ls "https://api.github.com/repos/MHSanaei/3x-ui/releases/latest" | grep '"tag_name":' | sed -E 's/.*"([^"]+)".*/\1/') if [[ ! -n "$tag_version" ]]; then echo -e "${red}Failed to fetch x-ui version, it may be due to GitHub API restrictions, please try it later${plain}" exit 1 fi echo -e "Got x-ui latest version: ${tag_version}, beginning the installation..." wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz if [[ $? -ne 0 ]]; then echo -e "${red}Downloading x-ui failed, please be sure that your server can access GitHub ${plain}" exit 1 fi else tag_version=$1 tag_version_numeric=${tag_version#v} min_version="2.3.5" if [[ "$(printf '%s\n' "$min_version" "$tag_version_numeric" | sort -V | head -n1)" != "$min_version" ]]; then echo -e "${red}Please use a newer version (at least v2.3.5). Exiting installation.${plain}" exit 1 fi url="https://github.com/MHSanaei/3x-ui/releases/download/${tag_version}/x-ui-linux-$(arch).tar.gz" echo -e "Beginning to install x-ui $1" wget -N -O /usr/local/x-ui-linux-$(arch).tar.gz ${url} if [[ $? -ne 0 ]]; then echo -e "${red}Download x-ui $1 failed, please check if the version exists ${plain}" exit 1 fi fi if [[ -e /usr/local/x-ui/ ]]; then systemctl stop x-ui rm /usr/local/x-ui/ -rf fi tar zxvf x-ui-linux-$(arch).tar.gz rm x-ui-linux-$(arch).tar.gz -f cd x-ui chmod +x x-ui # Check the system's architecture and rename the file accordingly if [[ $(arch) == "armv5" || $(arch) == "armv6" || $(arch) == "armv7" ]]; then mv bin/xray-linux-$(arch) bin/xray-linux-arm chmod +x bin/xray-linux-arm fi chmod +x x-ui bin/xray-linux-$(arch) cp -f x-ui.service /etc/systemd/system/ wget -O /usr/bin/x-ui https://raw.githubusercontent.com/MHSanaei/3x-ui/main/x-ui.sh chmod +x /usr/local/x-ui/x-ui.sh chmod +x /usr/bin/x-ui config_after_install systemctl daemon-reload systemctl enable x-ui systemctl start x-ui echo -e "${green}x-ui ${tag_version}${plain} installation finished, it is running now..." echo -e "" echo -e "┌───────────────────────────────────────────────────────┐ │ ${blue}x-ui control menu usages (subcommands):${plain} │ │ │ │ ${blue}x-ui${plain} - Admin Management Script │ │ ${blue}x-ui start${plain} - Start │ │ ${blue}x-ui stop${plain} - Stop │ │ ${blue}x-ui restart${plain} - Restart │ │ ${blue}x-ui status${plain} - Current Status │ │ ${blue}x-ui settings${plain} - Current Settings │ │ ${blue}x-ui enable${plain} - Enable Autostart on OS Startup │ │ ${blue}x-ui disable${plain} - Disable Autostart on OS Startup │ │ ${blue}x-ui log${plain} - Check logs │ │ ${blue}x-ui banlog${plain} - Check Fail2ban ban logs │ │ ${blue}x-ui update${plain} - Update │ │ ${blue}x-ui legacy${plain} - legacy version │ │ ${blue}x-ui install${plain} - Install │ │ ${blue}x-ui uninstall${plain} - Uninstall │ └───────────────────────────────────────────────────────┘" } echo -e "${green}Running...${plain}" install_base install_x-ui $1
3x-ui安装指南+搭建reality+申请ssl证书1 前言很久以前出过x-ui的视频和博客内容，但是由于时间过于久远，包括在技术上和更新上都有了一些变化，这里就重新写一下。github项目已经两年多没有更新了，当初x-ui的项目可谓是百花齐放，到现在剩余的项目确实不多了，目前稳定更新好用的x-ui面板就是今天要介绍的这个，伊朗作者的。伊朗的哥们真的是人才辈出，目前还在维护的有今天介绍的基于xray核心x-ui项目魔改的3x-ui。还有基于sing-box项目的web程序：https://github.com/alireza0/s-ui，还有另一个基于sing-box项目的下web程序，Hiddify-Manager超越X-UI还有另一个https://github.com/Gozargah/Marzban不过从另一个角度考虑，后续的几个项目在易用性上都很抽风，不愧是程序员出品的项目，用起来完全就没考虑过美观和易用性，实用价值最高的还是x-ui系列，所以还是优先推荐3x-ui项目。3x-ui的特色：系统状态监控在所有入口和客户端中搜索深度/浅色主题支持多用户和多协议支持多种协议，包括VMess、VLESS、Trojan、Shadowsocks、Dokodemo-door、Socks、HTTP、wireguard支持XTLS协议，包括RPRX-Direct、Vision、REALITY流量统计、流量限制、超时时间限制可自定义的 Xray 配置模板支持HTTPS访问面板（自建域名+SSL证书）支持一键式SSL证书申请和自动续费更多高级配置项目请参考面板修复了API路由（用户设置将使用API​​创建）支持通过面板中提供的不同项目更改配置。支持从面板导出/导入数据库1.1 3x-ui介绍3x-ui项目地址：https://github.com/MHSanaei/3x-ui基于x-ui后续魔改版本，和其余的x-ui魔改项目类似的是后续也更新了内核，并且支持了新的协议，支持多用户。不过3x-ui后续更新的实用功能是可以对xray核心进行修改，这点后续会讲。3x-ui在美观程度和动画流畅程度上和其余的搭建代理面板拉开了一个维度。2 安装3x-ui如果自动安装失败，可以采取手动安装的方式，详见本站文章：X-UI的手动安装教程，解救自动安装失败的VPS2.1 安装BBR安装3x-ui前记得安装bbr加速： Linux开启bbr的方法2.2 安装3x-ui安装脚本：bash <(curl -Ls https://raw.githubusercontent.com/mhsanaei/3x-ui/master/install.sh)在运行脚本以后，会提示你Do you want to continue with the modification y/n?这里的意思是是否要进行自定义配置，可以进行用户名和密码的自定义设置等，建议输入y进行自定义配置。Please set up your username: 后面输入要设置的面板用户名Please set up your password: 后面输入要设置的面板密码Please set up the panel port: 后面输入你要设置的面板端口然后就安装完成了，以后想要在ssh连接里面进行3x-ui的设置，只需要输入x-ui然后回车就会出现3x-ui的管理面板，如下：x-ui - Enter Admin menu x-ui start - Start x-ui x-ui stop - Stop x-ui x-ui restart - Restart x-ui x-ui status - Show x-ui status x-ui enable - Enable x-ui on system startup x-ui disable - Disable x-ui on system startup x-ui log - Check x-ui logs x-ui banlog - Check Fail2ban ban logs x-ui update - Update x-ui x-ui install - Install x-ui x-ui uninstall - Uninstall x-ui接下来我们就可以结束令人头疼的ssh设置，到简单容易操作的ui界面里面进行设置。2.3 x-ui网页端在浏览器输入你vps的IP，后面加上英文冒号，然后跟上你设置的端口，格式如下：IP:端口进入后在下方的语言设置里面设置为中文。然后输入你的用户名和密码进入。首页最上方会提示你此连接不安全。在激活 TLS 进行数据保护之前，请勿输入敏感信息。这里不用管，后续到了配置代理的时候在选择。主界面会显示一些信息：x-ui版本/IP地址/xray版本切换/瞬时网络流量/总共用了多少流量/连接数等等，方便查看。3 使用3.1 简单搭建reality在所有的翻墙协议里面，我最喜欢的就是reality协议，足够安全并且不需要自己的域名。如果需要自己的域名那么还得申请ssl，这里我们就简单示意一下reality的搭建点击左侧的入站列表，然后点击添加入站很多默认配置不需要修改，需要修改的几个栏目备注，这个随便写，就是节点名字。协议，默认就是vless，如果搭建reality协议就选vless。端口，最好是443，当然随便一个也行。传输，选tcp。安全，选中reality。然后关于私钥和公钥，点一下下面的 Get New Cert按钮就可以随机获取私钥和公钥。然后点击右下角的添加，就完成了一个reality节点的搭建。3.2 入站列表 栏目入站列表在入站列表栏目里面，上面是显示流量和用户等信息，下方是节点信息。可以看到我们已经搭建好了一个节点，节点的类型是vless tcp Reality这三个标签，关于如何导出节点链接，可以点击节点前方的三个点，然后点击导出链接，然后点击复制即可。4 3x-ui特色下面就是说一下为什么我要在写一篇博客介绍和x-ui类似的3x-ui项目，3x-ui有自己的xray设置，可以设置的东西很多。常规可以设置的东西如下：xray设置简单讲一下可以设置什么屏蔽BT协议/私有IP/广告/黄色网站/测速网站屏蔽连接到伊朗/中国/俄罗斯/越南的IP或者域名直连伊朗/中国/俄罗斯/越南的IP或者域名通过 IPv4 将流量路由到谷歌或者netflix自动配置warp，流量出站将通过cloudflare的warp进行代理。设置路由规则。设置出站规则，这里可以配置链式代理。负载均衡等。5 关于ssl证书3x-ui和其余的x-ui魔改类似，都可以很简单的申请证书，包括cloudflare自动申请证书，不过我们这里基本都是手动申请。开启面板ssl和节点开启ssl都需要证书，所以我们再讲一下如何申请证书。在ssh界面输入x-ui，弹出的列表里面，找到SSL Certificate Management对应的编号，我这个版本是16，那就输入16，然后回车。get ssl 代表申请证书。revoke 是撤销Force Renew 定时任务续签我们输入1，然后回车。提示Please enter your domain name: 后面输入你的域名提示please choose which port do you use,default will be 80 port:直接默认回车然后等待证书申请完成完成后会输出一些信息，包括如下Your cert is in:Your cert key is in:The intermediate CA cert is in:And the full chain certs is there:其中我们需要注意的是Your cert is in和Your cert key is in。Your cert is in:后面显示的内容是你的证书，Your cert key is in: 后面的显示内容是你的密钥，一般后面的有效内容会高亮显示。5.1 配置面板ssl我们回到面板，点击面板设置，在面板证书公钥文件路径里面粘贴你的公钥路径，在面板证书密钥文件路径里面填写你的私钥路径，然后在面板 url 根路径里面随便写一个路径，比如我这里写的是/panel然后点击上方的保存，然后点击重启面板。后续我们会发现通过IP直接访问进不去面板了，这很正常。现在我们需要通过https://你的域名:你设置的端口/你设置的路径 进入，这样可以有效提高面板的安全性。5.3 节点配置ssl接下来就很简单了，假如说我们需要一个带tls的节点，比如vmess+ws+tls，我们去入站列表新建一个配置，需要修改的是协议选择vmess，传输选择websocket，安全选择tls，然后点击下面的从面板设置证书，再点击下面的添加。就完成了一个vmess+ws+tls节点的创建。
sing-box 是什么sing-box 是新一代超强通用代理工具，对标 ray core 与 clash，而且它的性能以及支持的协议类型已经超过了 ray core 与 clash。目前支持以下协议：入站：Shadowsocks(including shadowsocks2022) Vmess Trojan Naive Hysteria ShadowTLS Vless Tuic Tun Redirect TProxy Socks HTTP出站：Shadowsocks(including shadowsocks2022) Vmess Trojan Wireguard Hysteria ShadowTLS ShadowsocksR VLESS Tuic Hysteria2 Tor SSH DNS关于如何在VPS安装Singbox服务器端可以查阅之前教程：233boy sing-box 一键安装脚本除了命令行客户端以外，还提供了图形界面客户端，图形界面支持 Android、iOS、macOS 以及 Apple tvOS，Windows 暂时不支持，还在施工中 这简直就是魔法上网界的瑞士军刀啊！而且所有的客户端都是免费的，iOS 端也不用再买 Shadowrocket 小火箭等付费 App 了。再看看隔壁 Surge 的价格,你玩我呢？？还是 sing-box 香。本文将会手把手教大家如何使用 sing-box 来实现任意机器的全局透明代理。sing-box 客户端下载第一步先解决客户端下载的问题。AndroidAndroid 客户端可以到 Play Store 中去下载,也可以直接到 GitHub Releases 页面下载。如果你是 Android 的 Magisk/KernelSU 玩家，可以选择刷入 box_for_magisk模块。Apple 平台iOS/macOS/Apple tvOS 用户可以到 App Store 中下载（前提是你得有个美区 ID），也可以使用 Homebrew 直接安装：$ brew install sfm除此之外你也可以直接到 GitHub Releases 页面下载客户端或者命令行版本。WindowsWindows 没有图形界面客户端，官方还正在开发中，不过可以直接使用包管理器 Sccop 或者 Chocolatey 安装命令行版本：# Sccop $ scoop install sing-box # Chocolatey $ choco install sing-box你也可以选择第三方开发者开发的图形界面客户端： GUI.for.SingBox还有一个更加成熟的第三方客户端： Hiddify-NextLinuxLinux 就很简单了，直接到 GitHub Releases 页面下载命令行版本即可。sing-box 配置解析sing-box 的核心就是它的配置，所有的配置都在一个 JSON 文件里，每个配置参数的含义可参考 sing-box 官方文档。但是为了能够快速使用起来，我们需要一个示例模板。没问题，我这就给你一个比较完美的透明代理模板：sing-box 透明代理示例模板下面我来给大家解析一下里面的配置，首先来看 DNS 部分。如果你嫌下面的解析太长不看，那就直接使用我的示例模板配置好了。DNS 配置sing-box 对 DNS 的处理比 Clash 强太多了，支持各种分流规则，结构如下：{ "dns": { "servers": [], "rules": [], "final": "", "strategy": "", "disable_cache": false, "disable_expire": false, "independent_cache": false, "reverse_mapping": false, "fakeip": {} } }其中 servers 定义了 DNS 服务器，具体参数含义我就不解释了，自己看官方文档。我给出的 DNS 服务器配置是：{ "dns": { "servers": [ { "tag": "dns_proxy", "address": "https://1.1.1.1/dns-query", "address_resolver": "dns_resolver", "strategy": "ipv4_only", "detour": "select" }, { "tag": "dns_direct", "address": "h3://dns.alidns.com/dns-query", "address_resolver": "dns_resolver", "strategy": "ipv4_only", "detour": "direct" }, { "tag": "dns_block", "address": "rcode://refused" }, { "tag": "dns_resolver", "address": "223.5.5.5", "strategy": "ipv4_only", "detour": "direct" } ] } }这里定义了 3 个 DNS 服务器，当你发起一个域名解析请求时，这些服务器会被用来查找对应的 IP 地址。同时还定义了一个 RCode 协议用来屏蔽请求。rules 定义了 DNS 规则，这些规则用于定义哪些域名应该使用哪个 DNS 服务器解析。它可以让你根据域名的特定模式选择不同的 DNS 服务器。DNS 规则如下：{ "dns": { "rules": [ { "outbound": "any", "server": "dns_resolver" // 注释：对于任何出站连接（不管是直接连接还是通过代理），使用 "dns_resolver" 服务器进行 DNS 解析（这一句主要用来解析代理节点本身的 IP 地址）。 }, { "clash_mode": "direct", "server": "dns_direct" // 注释：在直连模式（不经过代理）下，使用 "dns_direct" 服务器进行 DNS 解析。 }, { "clash_mode": "global", "server": "dns_proxy" // 注释：在全局代理模式下，使用 "dns_proxy" 服务器进行 DNS 解析。 }, { "process_name": [ "TencentMeeting", "NemoDesktop", "ToDesk", "ToDesk_Service", "WeChat", "Tailscale", "wireguard-go", "Tunnelblick", "softwareupdated", "kubectl" ], "server": "dns_direct" // 注释：当特定的进程（如 TencentMeeting、WeChat 等）发起 DNS 请求时，使用 "dns_direct" 服务器进行直连 DNS 解析。 }, { "domain_suffix": [ "icloudnative.io", "fuckcloudnative.io", "sealos.io", "cdn.jsdelivr.net" ], "server": "dns_direct" // 注释：对于特定后缀的域名（如 icloudnative.io 等），使用 "dns_direct" 服务器进行直连 DNS 解析。 }, { "process_name": ["DropboxMacUpdate", "Dropbox"], "server": "dns_proxy" // 注释：当 Dropbox 相关进程发起 DNS 请求时，使用 "dns_proxy" 服务器通过代理进行 DNS 解析。 }, { "package_name": [ "com.google.android.youtube", "com.android.vending", "org.telegram.messenger", "org.telegram.plus" ], "server": "dns_proxy" // 注释：对于特定的 Android 应用包名（如 YouTube、Telegram 等），使用 "dns_proxy" 服务器通过代理进行 DNS 解析。 }, { "rule_set": "geosite-geolocation-!cn", "server": "dns_proxy" // 注释：对于 geosite 数据库中定义的非中国地区的地理位置相关的域名，使用 "dns_proxy" 服务器通过代理进行 DNS 解析。 }, { "rule_set": "Global", "server": "dns_proxy" // 注释：对于定义在 "Global" 规则集中的域名，使用 "dns_proxy" 服务器通过代理进行 DNS 解析。 }, { "rule_set": [ "YouTube", "Telegram", "Netflix", "geoip-google", "geoip-telegram", "geoip-twitter", "geoip-netflix" ], "server": "dns_proxy" // 注释：对于特定的服务和地理位置相关的域名（如 YouTube、Netflix、谷歌、Telegram 相关的域名），使用 "dns_proxy" 服务器通过代理进行 DNS 解析。 } ], "final": "dns_direct" // 注释：如果上述规则都不适用，则默认使用 "dns_direct" 服务器进行直连 DNS 解析。 } }入站配置接下来比较重要的就是入站规则了，入站（Inbound）在网络领域，特别是在代理和网络路由配置中，通常指的是进入某个系统或网络的数据流。在 sing-box 中，入站配置定义了如何处理进入代理服务器的数据。入站配置示例如下：{ "inbounds": [ { "type": "tun", "inet4_address": "198.18.0.1/16", "auto_route": true, "exclude_package": [ "cmb.pb", "cn.gov.pbc.dcep", "com.MobileTicket", "com.adguard.android", "com.ainemo.dragoon", "com.alibaba.android.rimet", "com.alicloud.databox", "com.amazing.cloudisk.tv", "com.autonavi.minimap", "com.bilibili.app.in", "com.bishua666.luxxx1", "com.cainiao.wireless", "com.chebada", "com.chinamworld.main", "com.cmbchina.ccd.pluto.cmbActivity", "com.coolapk.market", "com.ctrip.ct", "com.dianping.v1", "com.douban.frodo", "com.eg.android.AlipayGphone", "com.farplace.qingzhuo", "com.hanweb.android.zhejiang.activity", "com.leoao.fitness", "com.lucinhu.bili_you", "com.mikrotik.android.tikapp", "com.moji.mjweather", "com.motorola.cn.calendar", "com.motorola.cn.lrhealth", "com.netease.cloudmusic", "com.sankuai.meituan", "com.sina.weibo", "com.smartisan.notes", "com.sohu.inputmethod.sogou.moto", "com.sonelli.juicessh", "com.ss.android.article.news", "com.ss.android.lark", "com.ss.android.ugc.aweme", "com.tailscale.ipn", "com.taobao.idlefish", "com.taobao.taobao", "com.tencent.mm", "com.tencent.mp", "com.tencent.soter.soterserver", "com.tencent.wemeet.app", "com.tencent.weread", "com.tencent.wework", "com.ttxapps.wifiadb", "com.unionpay", "com.unnoo.quan", "com.wireguard.android", "com.xingin.xhs", "com.xunmeng.pinduoduo", "com.zui.zhealthy", "ctrip.android.view", "io.kubenav.kubenav", "org.geekbang.geekTime", "tv.danmaku.bili" ], "stack": "mixed", "sniff": true }, { "type": "socks", "tag": "socks-in", "listen": "::", "listen_port": 5353 } ] }下面是对每个字段的详细注释：第一个入站连接的配置：type: "tun" 表示这是一个 tun 虚拟网络接口的配置。 inet4_address: "198.18.0.1/16" 设定了虚拟网络接口的 IPv4 地址和子网掩码。 auto_route: true 表示将自动处理路由，确保数据包正确传输。 exclude_package: 这是一个数组，包含了不通过此虚拟网络接口处理的 Android 应用程序包名列表。列出的 Android 应用程序将使用常规网络接口而不是虚拟接口。 stack: "mixed" 表示混合 system TCP 栈与 gvisor UDP 栈。 sniff: true 表示启用流量嗅探功能，以便自动检测和处理传入的数据流类型。第二个入站连接的配置：type: "socks" 表示这是一个 SOCKS 代理配置。 tag: "socks-in" 为这个入站连接定义了一个标签，方便在其它配置中引用。 listen: "::" 表示监听所有 IPv6 地址。如果需要监听所有 IPv4 地址，可以使用 "0.0.0.0"。 listen_port: 5353 定义了 SOCKS 代理监听的端口号。 其中 tun 接口是核心部分，我们将利用 tun 接口来实现全局透明代理。出站配置出站（Outbound）是指从本地网络或设备发出，向外部网络、服务或互联网发送的数据流量。示例出站配置如下：{ "outbounds": [ { "type": "selector", // 类型为选择器，用于在多个出站中选择一个 "tag": "select", // 标签名为 "select" "outbounds": [ "trojan-out" // 可选择的出站列表，这里只有 "trojan-out" ], "default": "trojan-out" // 默认选择的出站为 "trojan-out" }, { "type": "selector", // 同样是选择器类型 "tag": "openai", // 标签名为 "openai" "outbounds": [ "trojan-out" // 可选择的出站仍然是 "trojan-out" ], "default": "trojan-out" // 默认选择的出站同样是 "trojan-out" }, { "type": "selector", // 选择器类型 "tag": "tiktok", // 标签名为 "tiktok" "outbounds": [ "trojan-out" // 可选择的出站是 "trojan-out" ], "default": "trojan-out" // 默认选择的出站为 "trojan-out" }, { "type": "trojan", // 类型为 Trojan "tag": "trojan-out", // 标签名为 "trojan-out" "server": "xxxxxxxx", // Trojan 服务器地址 "server_port": 9443, // Trojan 服务器端口 "password": "xxxxxxxx", // Trojan 连接密码 "tls": { "enabled": true, // 启用 TLS 加密 "server_name": "xxxxxxxx", // TLS 服务器名称 "insecure": true, // 不验证 TLS 证书，用于自签名证书 "utls": { "fingerprint": "chrome" // 使用 Chrome 的 TLS 指纹 } }, "multiplex": { "protocol": "h2mux", // 使用 h2mux 多路复用协议 "max_connections": 4, // 最大连接数为 4 "min_streams": 4 // 每个连接的最小流数为 4 }, "transport": { "type": "grpc", // 传输协议为 gRPC "service_name": "TunService" // gRPC 服务名称 } }, { "type": "direct", // 直连类型，不通过代理直接访问 "tag": "direct" // 标签名为 "direct" }, { "type": "block", // 阻止类型，用于拦截流量 "tag": "block" // 标签名为 "block" }, { "type": "dns", // DNS 类型，用于 DNS 查询 "tag": "dns-out" // 标签名为 "dns-out" } ] }这个配置定义了不同类型的出站连接方式，包括选择器、Trojan、直连、阻止和 DNS 类型。每种类型都通过标签进行标识，便于在后续的路由规则中引用。路由配置路由部分才是 sing-box 的核心配置，这个部分定义了一系列规则和参数，用于决定如何处理不同的网络请求。通过这些规则和参数，sing-box 可以非常灵活地处理复杂的路由需求，包括基于地理位置、IP 地址、端口号、域名等多种条件的流量分流。配置结构如下：{ "route": { "rules": [], "rule_set": [], "final": "direct", // "final" 字段定义了默认的路由行为。这里设置为 "direct"，意味着如果没有匹配任何规则，流量将直接（不经代理）发送。 "auto_detect_interface": true // 表示自动检测网络接口。这有助于自动适应网络变化，确保路由正确。 } }其中的核心配置：路由规则 (rules): 这些规则定义了如何根据不同的条件将流量定向到不同的出站连接。每个规则可以包括多个条件，如域名、IP 地址、端口号、网络协议等。规则集 (rule_set): 从 sing-box 1.8.0 版本开始，规则可以组合成规则集，这使得配置更加灵活和模块化。路由规则以下是我给出的路由规则示例：{ "route": { "rules": [ { "protocol": "dns", // 使用DNS协议的流量 "outbound": "dns-out" // 将通过'dns-out'出口转发 }, { "clash_mode": "direct", // Clash模式为直连 "outbound": "direct" // 将通过'direct'出口直接连接 }, { "clash_mode": "global", // Clash模式为全局 "outbound": "select" // 将通过'select'出口选择转发 }, { "domain_suffix": [ // 特定后缀的域名 "icloudnative.io", "fuckcloudnative.io", "sealos.io", "cdn.jsdelivr.net" ], "outbound": "direct" // 将通过'direct'出口直接连接 }, { "process_name": [ // 特定进程名称 "TencentMeeting", "NemoDesktop", ... ], "outbound": "direct" // 将通过'direct'出口直接连接 }, { "rule_set": [ // 特定的规则集 "WeChat", "Bilibili" ], "outbound": "direct" // 将通过'direct'出口直接连接 }, { "protocol": "quic", // 使用QUIC协议的流量 "outbound": "block" // 将被阻止 }, { "inbound": "socks-in", // 来自'socks-in'入口的流量 "outbound": "select" // 将通过'select'出口选择转发 }, { "rule_set": "OpenAI", // OpenAI规则集 "outbound": "openai" // 将通过'openai'出口转发 }, { "domain_suffix": [ // OpenAI相关的域名后缀 "openai.com", "oaistatic.com", "oaiusercontent.com" ], "outbound": "openai" // 将通过'openai'出口转发 }, { "package_name": "com.openai.chatgpt", // OpenAI ChatGPT应用包名 "outbound": "openai" // 将通过'openai'出口转发 }, { "rule_set": "TikTok", // TikTok规则集 "outbound": "tiktok" // 将通过'tiktok'出口转发 }, { "package_name": "com.zhiliaoapp.musically", // TikTok应用包名 "outbound": "tiktok" // 将通过'tiktok'出口转发 }, { "domain_suffix": [ // 特定的域名后缀 "depay.one", "orbstack.dev" ], "outbound": "select" // 将通过'select'出口选择转发 }, { "process_name": [ // 特定的进程名称 "DropboxMacUpdate", "Dropbox" ], "outbound": "select" // 将通过'select'出口选择转发 }, { "package_name": [ // 特定应用包名 "com.google.android.youtube", ... ], "outbound": "select" // 将通过'select'出口选择转发 }, { "domain": "accounts.google.com", // 特定的域名 "domain_suffix": [ // 特定的域名后缀 "sourceforge.net", "fhjasokiwq.com" ], "outbound": "select" // 将通过'select'出口选择转发 }, { "domain_suffix": "cloud.sealos.io", // 特定的域名后缀 "outbound": "direct" // 将通过'direct'出口直接连接 }, { "type": "logical", // 逻辑类型规则 "mode": "and", // 使用'and'模式 "rules": [ // 组合规则 { "rule_set": "geosite-geolocation-!cn" }, { "rule_set": "geoip-cn", "invert": true } ], "outbound": "select" // 将通过'select'出口选择转发 }, { "rule_set": "Global", // Global规则集 "outbound": "select" // 将通过'select'出口选择转发 }, { "rule_set": "geoip-cn", // 中国地理位置IP规则集 "outbound": "direct" // 将通过'direct'出口直接连接 }, { "ip_is_private": true, // 私有IP地址 "outbound": "direct" // 将通过'direct'出口直接连接 }, { "rule_set": [ // 特定的规则集 "YouTube", "Telegram", "Netflix", "geoip-google", "geoip-telegram", "geoip-twitter", "geoip-netflix" ], "outbound": "select" // 将通过'select'出口选择转发 } ] } }这个配置定义了不同类型的流量（如基于协议、域名后缀、应用包名、进程名称等）如何被路由。每条规则都指定了一种流量类型和相应的“出口”，即流量应该如何被处理或转发。这种灵活的路由配置可以非常精确地控制网络流量。规则集以下是我给出的规则集示例：{ "route": { "rule_set": [ { "type": "remote", "tag": "geosite-geolocation-!cn", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/SagerNet/sing-geosite/rule-set/geosite-geolocation-!cn.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-cn", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-cn.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-google", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-google.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-telegram", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-telegram.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-twitter", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-twitter.srs", "download_detour": "direct" }, { "type": "remote", "tag": "geoip-netflix", "format": "binary", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/CHIZI-0618/v2ray-rules-dat/release/singbox_ip_rule_set/geoip-netflix.srs", "download_detour": "direct" }, { "type": "remote", "tag": "Global", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Global.json", "download_detour": "direct" }, { "type": "remote", "tag": "YouTube", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/YouTube.json", "download_detour": "direct" }, { "type": "remote", "tag": "OpenAI", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/OpenAI.json", "download_detour": "direct" }, { "type": "remote", "tag": "TikTok", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/TikTok.json", "download_detour": "direct" }, { "type": "remote", "tag": "Telegram", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Telegram.json", "download_detour": "direct" }, { "type": "remote", "tag": "Netflix", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Netflix.json", "download_detour": "direct" }, { "type": "remote", "tag": "WeChat", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/WeChat.json", "download_detour": "direct" }, { "type": "remote", "tag": "Bilibili", "format": "source", "url": "https://mirror.ghproxy.com/https://raw.githubusercontent.com/yangchuansheng/sing-box-geosite/main/rule/Bilibili.json", "download_detour": "direct" } ] } }这里有两种不同类型的规则集，一种是 binary，另外一种是 source。binary 规则集一般都是利用 GEOSITE 或者 GEOIP 直接编译好的二进制规则，它们被直接嵌入到应用程序中。而 source 规则集就和 Clash 的 ruleset 比较类似，它是一个文本文件，而不是二进制。目前已经有相关项目可以自动将网络上的 Clash Ruleset 规则自动转换为 sing-box 的 source 规则集，感兴趣的同学可以参考这个项目： sing-box-geositeClash API最后的实验性配置用来开启 Clash API。没错，sing-box 是兼容 Clash API 滴！那么我们就可以使用 Clash 的 dashboard 来管理 sing-box 了，直接用这个项目好了： metacubexd示例配置如下：{ "experimental": { "cache_file": { "enabled": true // 启用缓存文件功能。当此项设置为true时，启用 DNS 查询的缓存，以便加快后续相同查询的响应速度。 }, "clash_api": { "external_controller": "0.0.0.0:9090", // 定义 Clash API 的外部控制器地址。"0.0.0.0:9090" 表示在本机的9090端口上监听外部的连接请求。 "external_ui": "metacubexd", // 指定外部用户界面(UI)的名称。这里的 "metacubexd" 是一个自定义 UI 的名称。 "external_ui_download_url": "https://github.com/MetaCubeX/metacubexd/archive/refs/heads/gh-pages.zip", // 提供外部 UI 的下载 URL。这个 URL 是从 GitHub 上下载 "metacubexd" UI 的压缩包。 "external_ui_download_detour": "select", // 定义下载外部 UI 时使用的转发策略。"select" 表示将通过'select'出口选择转发 "default_mode": "rule" // 设置 Clash API 的默认模式。"rule" 模式意味着流量将根据用户定义的规则进行路由。 } } }最终启动 sing-box 之后就可以通过 Clash dashboard 来查看和管理流量啦：注意： 图形界面客户端会自动把外部控制器相关的配置给屏蔽掉，如果你想使用 Dashboard，只能使用命令行来启动 sing-box。订阅转换我想大部分小伙伴使用的还是订阅链接，不可能傻乎乎的自己写配置和规则。但是目前大部分ji场都不提供 sing-box 的配置格式，仅有少量ji场提供支持，其他ji场可使用下面这个项目将常见订阅转换为 sing-box 订阅格式： sing-box-subscribe你可以将这个项目部署到自己的 Vercel 中，然后使用以下的链接格式来将常见订阅转换为 sing-box 订阅格式：<URL>/url=<subscription_url>/&file=<sing-box_template_url> <URL>：这是你的 sing-box-subscribe 访问链接； <subscription_url>：这是你的订阅链接； <sing-box_template_url>：这是你的 sing-box 模板配置链接，你可以直接使用 我的模板。例如：https://sing-box-subscribe.vercel.app/config/url=https://xxxxxx?clash=1/&file=https://gist.githubusercontent.com/yangchuansheng/5182974442015feeeeb058de543a00fd/raw/45b11ff08188af021da98e7174923d719dc42dd9/gistfile1.txt如果你有多个订阅链接，需要先将订阅链接合并为一个链接，然后再进行转换，具体看参考 sing-box-subscribe 的官方文档。更多配置示例更多的配置示例可以参考这个项目： sing-box-examples这个项目针对每一个代理协议都提供了详细的配置示例，还有很多的骚操作，比如 将 Cloudflare 的 Warp 节点信息直接提取出来加到 sing-box 出站配置中去，妙啊！透明网关如果你想让局域网中的所有机器都能够根据规则智能分流，那就在局域网中找一台机器作为透明网关，在这台机器上运行一个 sing-box 就行了，不需要像 Clash 一样写什么乱七八糟的 iptables 规则，直接一个配置文件就行了，非常简单。通常我们使用软路由来完成这个任务，如果你不想使用软路由，那随便找一台机器就行了，当然最好还是使用 Linux 比较靠谱。在网关上运行 sing-box 之后，其他机器只需要将网关指向这台机器，便可以无痛开启魔法智能分流了。注意： 其他机器的 DNS 必须是公网 DNS，不能使用内网 DNS！你的 DNS 可以指向任意的公网 DNS，反正只要是公网就行，比如：114.114.114.114，因为 sing-box 会劫持局域网中的所有 DNS 请求。当然，如果你不想让 sing-box 劫持局域网中的所有 DNS 请求，可以使用如下的方案：首先在入站配置中添加一个监听端口：{ "inbounds": [ { "type": "direct", "tag": "dns-in", "listen": "0.0.0.0", "listen_port": 53 } ] }然后在路由规则中将 DNS 的规则改成如下的配置： { "route": { "rules": [ { "inbound": "dns-in", "outbound": "dns-out" } ] } }这样就保证了只有从 53 端口进来的流量才会进入 DNS 解析。重启生效后，将其他机器的网关和 DNS 均指向这台机器就可以了。如果你使用的是 DHCP，只需要在 DHCP 服务器中将 DHCP 分配的网关和 DNS 改成 sing-box 所在的机器 IP 即可。