{"id":17923097,"url":"https://github.com/xiu2/sniproxy","last_synced_at":"2025-04-09T05:13:03.104Z","repository":{"id":172951556,"uuid":"650007588","full_name":"XIU2/SNIProxy","owner":"XIU2","description":"🧷 自用的简单 SNIProxy（常用于网站负载均衡、基于域名(SNI)的端口转发等","archived":false,"fork":false,"pushed_at":"2024-09-27T08:07:07.000Z","size":65,"stargazers_count":394,"open_issues_count":5,"forks_count":63,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-04-01T11:08:31.882Z","etag":null,"topics":["go","golang","http","sniproxy"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/XIU2.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-06-06T06:13:14.000Z","updated_at":"2025-03-31T07:51:33.000Z","dependencies_parsed_at":"2024-03-19T15:59:51.681Z","dependency_job_id":"0b192b2f-09be-47eb-950d-583fdc385b72","html_url":"https://github.com/XIU2/SNIProxy","commit_stats":null,"previous_names":["xiu2/sniproxy"],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XIU2%2FSNIProxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XIU2%2FSNIProxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XIU2%2FSNIProxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/XIU2%2FSNIProxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/XIU2","download_url":"https://codeload.github.com/XIU2/SNIProxy/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247980843,"owners_count":21027808,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","http","sniproxy"],"created_at":"2024-10-28T20:42:07.948Z","updated_at":"2025-04-09T05:13:03.080Z","avatar_url":"https://github.com/XIU2.png","language":"Go","readme":"# XIU2/SNIProxy\n\n[![Go Version](https://img.shields.io/github/go-mod/go-version/XIU2/SNIProxy.svg?style=flat-square\u0026label=Go\u0026color=00ADD8\u0026logo=go)](https://github.com/XIU2/SNIProxy/)\n[![Release Version](https://img.shields.io/github/v/release/XIU2/SNIProxy.svg?style=flat-square\u0026label=Release\u0026color=00ADD8\u0026logo=github)](https://github.com/XIU2/SNIProxy/releases/latest)\n[![GitHub license](https://img.shields.io/github/license/XIU2/SNIProxy.svg?style=flat-square\u0026label=License\u0026color=00ADD8\u0026logo=github)](https://github.com/XIU2/SNIProxy/)\n[![GitHub Star](https://img.shields.io/github/stars/XIU2/SNIProxy.svg?style=flat-square\u0026label=Star\u0026color=00ADD8\u0026logo=github)](https://github.com/XIU2/SNIProxy/)\n[![GitHub Fork](https://img.shields.io/github/forks/XIU2/SNIProxy.svg?style=flat-square\u0026label=Fork\u0026color=00ADD8\u0026logo=github)](https://github.com/XIU2/SNIProxy/)\n\n🧷 自用的一个功能很简单的 SNIProxy 顺便分享出来给有同样需求的人，用得上的话可以**点个⭐支持下~**\n\nSNIProxy 是一个根据传入域名(SNI)来自动端口转发至该域名源服务器的工具，常用于网站多服务器**负载均衡**，而且因为是通过明文的 SNI 来获取目标域名，因此**不需要 SSL 解密再加密**，转发速度和效率自然也大大提高了。\n\n\u003e [!IMPORTANT]\n\u003e 注意！SNIProxy 只是起到一个**端口转发、负载均衡**的作用。简单的来说就是 SNIProxy 收到的所有数据都会被**原封不动**的转发给目标源服务器（包括明文的 SNI 域名信息，任何第三方例如墙依然能直接看到），因此 SNIProxy 是 **`无法用来番墙`** 的（否则就是脱裤子放屁 —— **多此一举**！ 毕竟墙早就可以 域名(SNI)阻断 了）。\n\n\u003e _分享我其他开源项目：[**TrackersList.com** - 全网热门 BT Tracker 列表！有效提高 BT 下载速度~](https://github.com/XIU2/TrackersListCollection) \u003cimg src=\"https://img.shields.io/github/stars/XIU2/TrackersListCollection.svg?style=flat-square\u0026label=Star\u0026color=4285dd\u0026logo=github\" height=\"16px\" /\u003e_  \n\u003e _[**CloudflareSpeedTest** - 🌩「自选优选 IP」测试 Cloudflare CDN 延迟和速度，获取最快 IP~](https://github.com/XIU2/CloudflareSpeedTest) \u003cimg src=\"https://img.shields.io/github/stars/XIU2/CloudflareSpeedTest.svg?style=flat-square\u0026label=Star\u0026color=4285dd\u0026logo=github\" height=\"16px\" /\u003e_  \n\u003e _[**UserScript** - 🐵 Github 高速下载、知乎增强、自动无缝翻页、护眼模式 等十几个**油猴脚本**~](https://github.com/XIU2/UserScript) \u003cimg src=\"https://img.shields.io/github/stars/XIU2/UserScript.svg?style=flat-square\u0026label=Star\u0026color=4285dd\u0026logo=github\" height=\"16px\" /\u003e_\n\n\n****\n\n## \\# 软件介绍\n\n- **支持** 全平台、全系统（Go 语言特性）\n- **支持** Socks5 前置代理（比如可以再套一层 WARP，这样 SNIProxy 的出口 IP 就是 Cloudflare 的了）\n- **支持** 允许转发所有域名  或 仅允许转发指定域名（包含域名自身及其所有子域名）\n- **支持** 单独或同时监听及传输 IPv4、IPv6 流量\n- **支持** 根据明文 SNI(域名/主机名) 来自动转发流量到该域名的源服务器，无需加解密流量，无需 SSL 密钥或证书\n\n\u003e [!WARNING]\n\u003e 注意！SNIProxy 仅为我个人自写自用，**可靠性、稳定性**等方面**不如专业的商业软件（如 Nginx、HAProxy）**，因此在正式的**生产环境下不建议使用本软件**，如造成损失，根据 GPL-3.0 本项目无需承担责任（溜了溜了~  \n\n\u003e [!NOTE]\n\u003e 另外，Web 流量一直在不断发展，目前流行的 **HTTP/2** 可以在单个 TCP 流中复用多个主机名，这会导致 SNIProxy **无法根据主机名(域名)来正确转发流量**（因为多个混在了一起）。而 **HTTP/3 (QUIC)** 更是改用 UDP 协议传输，这和 TCP 协议是完全不同的。**SNIProxy 不支持这些协议，也不会去添加支持**，因为这会使项目变得极其复杂（也超出了我的能力，毕竟我只是为了方便自己使用而边学边写的，代码也才几百行罢了）。\n\n****\n\nSNIProxy 的工作流程大概如下：\n\n1. 解析传入连接中的 TLS/SSL 握手消息，以获取访客发送的 **SNI 域名**信息。\n2. 检查域名是否在允许列表中（或开启了 `allow_all_hosts`），如果不在将中断连接，反之继续。\n3. 使用系统 DNS 解析 SNI 域名获得 IP 地址（即该域名的源站服务器 IP 地址）。\n4. 将收到的数据原封不动的转发给该域名的源站 **IP:443**，在访客和源站之间建立一个 \"桥梁\" 进行持续的相互数据传输（即 TCP 中转/端口转发）。\n\n```javascript\n// 将 example.com 域名指向 SNIProxy 服务器的 IP，然后：\n访问 example.com \u003c=\u003e SNIProxy(解析 SNI 获得目标域名) \u003c=\u003e 源站(example.com)\n\n// 按照工作流程更详细一点的：\n访问 example.com \u003c=\u003e SNIProxy [ 解析 SNI 获得 example.com 域名 \u003c=\u003e 检查该域名是否在允许转发 \u003c=\u003e 系统 DNS 解析该域名获得 IP 地址 ] \u003c=\u003e 源站(example.com)\n\n\n// 例如：当有多台服务器配置 SNIProxy 后，可以在域名 DNS 解析中指向这些服务器 IP，这样访客就会被随机分配到其中一个服务器上，实现分流负载均衡等。\n// 也可以依靠 DNS 区域解析来给不同地区、运营商的访客指向离它们更近、线路更优的服务器 IP，来间接提高网站的访问速度，提升用户体验。\n\n// 如果 SNIProxy 开启了前置代理，那么就是这样：\n访问 example.com \u003c=\u003e SNIProxy \u003c=\u003e Socks5(解析 SNI 获得目标域名) \u003c=\u003e 源站(example.com)\n```\n\n\u003e [!TIP]\n\u003e SNIProxy 本质上也是一种**端口转发（中转）**，但不同于端口转发只能指定一个**固定的目标 IP**，SNIProxy 可以通过 DNS 解析传入的域名来获得**灵活的目标 IP**（传入不同的域名走不同目标 IP，可**同时存在**且**互不干扰**）。\n\n****\n\n## \\# 使用方法\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击查看 Linux 系统下的使用示例 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n以下命令仅为示例，版本号和文件名请前往 [**Releases**](https://github.com/XIU2/SNIProxy/releases) 查看。\n\n```yaml\n# 如果是第一次使用，则建议创建新文件夹（后续更新时，跳过该步骤）\nmkdir sniproxy\n\n# 进入文件夹（后续更新，只需要从这里重复下面的下载、解压命令即可）\ncd sniproxy\n\n# 下载 sniproxy 压缩包（自行根据需求替换 URL 中 [版本号] 和 [文件名]）\nwget -N https://github.com/XIU2/SNIProxy/releases/download/v1.0.4/sniproxy_linux_amd64.tar.gz\n# 如果你是在国内服务器上下载，那么请使用下面这几个镜像加速：\n# wget -N https://ghp.ci/https://github.com/XIU2/SNIProxy/releases/download/v1.0.4/sniproxy_linux_amd64.tar.gz\n# wget -N https://ghproxy.cc/https://github.com/XIU2/SNIProxy/releases/download/v1.0.4/sniproxy_linux_amd64.tar.gz\n# wget -N https://ghproxy.net/https://github.com/XIU2/SNIProxy/releases/download/v1.0.4/sniproxy_linux_amd64.tar.gz\n# wget -N https://gh-proxy.com/https://github.com/XIU2/SNIProxy/releases/download/v1.0.4/sniproxy_linux_amd64.tar.gz\n\n# 如果下载失败的话，尝试删除 -N 参数（如果是为了更新，则记得提前删除旧压缩包 rm sniproxy_linux_amd64.tar.gz ）\n\n# 解压（不需要删除旧文件，会直接覆盖，自行根据需求替换 文件名）\ntar -zxf sniproxy_linux_amd64.tar.gz\n\n# 赋予执行权限\nchmod +x sniproxy\n\n# 编辑配置文件（根据下面的 配置文件说明 来自定义配置内容并保存(按下 Ctrl+X 然后再按 2 下回车)\nnano config.yaml\n\n# 运行（不带参数）\n./sniproxy\n\n# 运行（带参数示例）\n./sniproxy -c \"config.yaml\"\n\n# 后台运行（带参数示例）\nnohup ./sniproxy -c \"config.yaml\" \u003e \"sni.log\" 2\u003e\u00261 \u0026\n```\n\n\u003e 另外，强烈建议顺便提高一下 [系统文件句柄数上限](https://github.com/XIU2/SNIProxy#-提高系统文件句柄数上限-避免报错-too-many-open-files)，避免遇到报错 **too many open files**\n\n\u003e 另外，如果你希望 **开机启动、守护进程(异常退出自动恢复)、后台运行、方便管理** 等，那么可以将其 [注册为系统服务](https://github.com/XIU2/SNIProxy#-linux-配置为系统服务-systemd---以支持开机启动守护进程等)。\n\n\u003c/details\u003e\n\n****\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击查看 Windows 系统下的使用示例 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n### 下载\n\n下载已编译好的可执行文件并解压：\n\n1. [Github Releases](https://github.com/XIU2/SNIProxy/releases)  \n2. [蓝奏云](https://pan.lanpw.com/b077bn2ri)(密码:xiu2)\n\n### 配置\n\n找到配置文件 `config.yaml` 右键菜单 - 打开方式 - 记事本。\n\n根据下面的 [配置文件说明](https://github.com/XIU2/SNIProxy#-配置文件说明-configyaml) 来自定义配置内容并保存。\n\n### 运行\n\n双击运行 `sniproxy.exe` 文件。\n\n或者在 CMD 命令行中进入软件所在目录并运行 `sniproxy.exe`：\n\n```yaml\n# CMD 命令行中进入解压后的 sniproxy 程序所在目录（记得修改下面示例路径）\ncd /d C:\\xxx\\sniproxy\n\n# 运行（不带参数）\nsniproxy.exe\n\n# 运行（带参数示例）\nsniproxy.exe -c \"config.yaml\"\n```\n\u003c/details\u003e\n\n****\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击查看 Mac 系统下的使用示例 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n下载已编译好的可执行文件并解压：\n\n1. [Github Releases](https://github.com/XIU2/SNIProxy/releases)  \n2. [蓝奏云](https://pan.lanpw.com/b077bn2ri)(密码:xiu2)\n\n```yaml\n# 通过命令行进入 sniproxy 压缩包所在目录（记得修改下面示例路径）\ncd /xxx/xxx\n\n# 解压（不需要删除旧文件，会直接覆盖，自行根据需求替换 文件名）\ntar -zxf sniproxy_linux_amd64.tar.gz\n\n# 赋予执行权限\nchmod a+x sniproxy\n\n# 编辑配置文件（根据下面的 配置文件说明 来自定义配置内容并保存(按下 Contrl+X 然后再按 2 下回车)\nnano config.yaml\n\n# 运行（不带参数）\n./sniproxy\n\n# 运行（带参数示例）\n./sniproxy -c \"config.yaml\"\n```\n\n\u003c/details\u003e\n\n****\n\n```css\nhome@xiu:~# ./sniproxy -h\n\nSNIProxy vX.X.X\nhttps://github.com/XIU2/SNIProxy\n\n参数：\n    -c config.yaml\n        配置文件 (默认 config.yaml)\n    -l sni.log\n        日志文件 (默认 无)\n    -d\n        调试模式 (默认 关)\n    -v\n        程序版本\n    -h\n        帮助说明\n```\n\n****\n\n## \\# 其他说明\n\n#### \\# 配置文件说明 (config.yaml)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击展开 查看内容 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n\u003e **注意：** 配置文件是 YAML 格式，即按照缩进（即每行前面的空格数量）来确定层级关系的，因此不懂的话请按照默认配置文件内示例的格式为准，其中 ` # ` 的是注释（会被程序忽略），不需要的配置可以注释掉。\n\n目前配置文件中的配置项没几个，分别为：\n\n```yaml\n# 监听端口（注意需要引号），常见示例如下：\n# \":443\"            省略 IP 只写端口，代表监听本机所有 IPv4+IPv6 地址的 443 端口\n# \"0.0.0.0:443\"     代表监听本机所有 IPv4 地址的 443 端口\n# \"127.0.0.1:443\"   代表监听本机本地 IPv4 地址的 443 端口（只有本机可访问）\n# \"[::]:443\"        代表监听本机所有 IPv6 地址的 443 端口\n# \"[::1]:443\"       代表监听本机本地 IPv6 地址的 443 端口（只有本机可访问）\n# 上面示例中的 IP 地址也可以换成例如你的外网 IP，这样的话就只能从该外网 IP 访问了\nlisten_addr: \":443\"\n\n# 可选：启用 Socks5 前置代理\n# （启用前：访客 \u003c=\u003e SNIProxy \u003c=\u003e 目标网站\n# （启用后：访客 \u003c=\u003e SNIProxy \u003c=\u003e Socks5 \u003c=\u003e 目标网站\n# （比如可以套 WARP，那样就变成：访客 \u003c=\u003e SNIProxy \u003c=\u003e WARP \u003c=\u003e 目标网站\nenable_socks5: true\n# 可选：配置 Socks5 代理地址\nsocks_addr: 127.0.0.1:40000\n\n# 可选：允许所有域名（开启后会忽略下面的 rules 列表）\nallow_all_hosts: true\n\n# 可选：仅允许指定域名（和上面的 allow_all_hosts 二选一）\n# 指定域名后，则代表允许 域名自身 及其 所有子域名 访问服务（以下方两个为例，√ 代表允许，× 代表阻止）\nrules:\n  - example.com #    example.com  √ 、a.example.com  √ 、a.a.example.com  √\n  - b.example2.com # example2.com × 、b.example2.com √ 、c.b.example2.com √\n```\n\n****\n\n一些示例：\n\n1. 允许所有域名访问\n\n```yaml\nlisten_addr: \":443\"\nallow_all_hosts: true\n```\n\n\u003e 注意，开启 allow_all_hosts 时，可能会被他人扫描到而滥用，请悉知！  \n\u003e 建议做一些限制，例如只使用 IPv6（`\"[::]:443\"`）或防火墙限制 443 端口的可访问 IP。\n\n2. 仅允许指定域名\n\n```yaml\nlisten_addr: \":443\"\nrules:\n  - example.com\n  - b.example2.com\n```\n\n3. 允许所有域名访问 + 启用前置代理\n\n```yaml\nlisten_addr: \":443\"\nenable_socks5: true\nsocks_addr: 127.0.0.1:40000\nallow_all_hosts: true\n```\n\n4. 仅允许指定域名 + 启用前置代理\n\n```yaml\nlisten_addr: \":443\"\nenable_socks5: true\nsocks_addr: 127.0.0.1:40000\nrules:\n  - example.com\n  - b.example2.com\n```\n\n\u003c/details\u003e\n\n****\n\n#### \\# Linux 配置为系统服务 (systemd - 以支持开机启动、守护进程等)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击展开 查看内容 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n新建一个空的名叫 **sniproxy** 的系统服务配置文件：\n\n```yaml\nnano /etc/systemd/system/sniproxy.service\n```\n\n修改以下内容后（`ExecStart=` 后面的程序路径、参数）后粘贴进文件内：\n\n```ini\n[Unit]\nDescription=SNI Proxy\nAfter=network.target\n\n[Service]\nExecStart=/home/sniproxy/sniproxy -c /home/sniproxy/config.yaml -l /home/sniproxy/sni.log\nRestart=on-failure\n\n[Install]\nWantedBy=multi-user.target\n```\n\n\u003e 其中 `Restart=on-failure` 表示，当程序非正常退出时，会自动恢复启动，也就是常说的守护进程。\n\n设置 **sniproxy** 开机启动并立即启动：\n\n```yaml\n# 启用该系统服务 并 允许开机启动\nsystemctl enable sniproxy\n\n# 立即启动\nsystemctl start sniproxy\n```\n\n其他可能会用到的命令：\n\n```yaml\n# 停止\nsystemctl stop sniproxy\n\n# 重启\nsystemctl restart sniproxy\n\n# 查看运行状态\nsystemctl status sniproxy\n\n# 查看完整日志\ncat /home/sniproxy/sni.log\n\n# 实时监听日志（会实时显示最新日志内容）\ntail -f /home/sniproxy/sni.log\n\n# 如果你修改了 /etc/systemd/system/sniproxy.service 配置文件，那么需要先重载配置后才能启动/重启 sniproxy 服务\nsystemctl daemon-reload\n```\n\u003c/details\u003e\n\n****\n\n#### \\# SNIProxy 优先通过 IPv4 还是 IPv6 转发流量给目标域名源服务器？\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击展开 查看内容 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n首先需要清楚，SNIProxy 是通过 IPv4 还是 IPv6 地址转发流量给目标域名源服务器，和你是通过 IPv4 还是 IPv6 访问 SNIProxy 服务***无关***，`\"你 与 SNIProxy\"` 和 `\"SNIProxy 与 源服务器\"` **这两个环节是独立的，互不影响的**。\n\n因为 SNIProxy 的 DNS 解析环节是交由系统 DNS 服务处理的，因此对于 SNIProxy 是通过 IPv4 还是 IPv6 地址转发流量给目标域名源服务器，则取决于：\n1. 运行 SNIProxy 的服务器**是否有 IPv4 或 IPv6 地址**（或都有，也就是双栈服务器）\n2. 运行 SNIProxy 的服务器当前系统配置的 **DNS 优先级是 IPv4 优先还是 IPv6 优先**（一般默认都是 IPv6 优先）\n3. 该目标域名解析记录中**是否有 IPv4 或 IPv6 地址**（也就是 A 和 AAAA 记录）\n\n即，如果你的服务器有 IPv6 地址，且系统为默认的 IPv6 优先，那么无论你是通过 IPv4 还是 IPv6 访问的 SNIProxy 服务器，只要该域名有 IPv6 解析地址，那么 SNIProxy 就会通过 IPv6 转发流量给目标域名源服务器。\n\n```javascript\n访问 example.com \u003c=IPv4=\u003e SNIProxy \u003c=优先 IPv6=\u003e 系统 DNS 解析获得该域名的 IP 地址  \u003c=IPv6=\u003e 源站(example.com)\n\n访问 example.com \u003c=IPv6=\u003e SNIProxy \u003c=优先 IPv6=\u003e 系统 DNS 解析获得该域名的 IP 地址  \u003c=IPv6=\u003e 源站(example.com)\n```\n\n假如目标域名解析只有 IPv6 地址，你本地只有 IPv4 地址，但你的服务器有 IPv4+IPv6 地址，那么你就可以通过 IPv4 来访问 SNIProxy，然后 SNIProxy 通过 IPv6 访问目标域名源服务器。\n\n```javascript\n访问 example.com(仅 IPv4) \u003c=IPv4=\u003e SNIProxy(支持 IPv4+IPv6)  \u003c=IPv6=\u003e 源站(example.com 仅 IPv6)\n```\n\n****\n\n关于这个系统 DNS 服务的 IPv4 IPv6 优先级是可以调的（以下为**将默认的 IPv6 优先改为 IPv4 优先**）：\n\n打开并编辑文件（你也可以使用 vim 来编辑）：\n```yaml\nnano /etc/gai.conf\n```\n\n找到以下行：\n```yaml\n#precedence ::ffff:0:0/96  100\n```\n去掉改行行首的 `#` 注释符号，使其变为：\n\n\u003e 如果没有找到的话，可以直接在文件末尾另起一行写上下面这行代码。\n\n```yaml\nprecedence ::ffff:0:0/96  100\n```\n按下 `Ctrl+O` 并回车保存文件，然后再按下 `Ctrl+X` 退出当前的 nano 编辑器。\n\n此时随便 `ping` 一个同时拥有 IPv4 及 IPv6 地址的域名，看一下结果是不是 IPv4 地址。\n\n\u003e 另外，修改系统 DNS 优先级后，可能需要清理服务器的 DNS 缓存并重启 SNIProxy 服务。\n\n\u003c/details\u003e\n\n****\n\n#### \\# 提高系统文件句柄数上限 (避免报错 too many open files)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击展开 查看内容 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\nLinux 系统下，一些人可能会遇到报错（日志如下）：\n```\n接受连接请求时出错: accept tcp [::]:443: accept4: too many open files\n```\n\n这是因为系统的文件句柄数耗尽了（默认 1024），提高系统文件句柄数上限可有效缓解该问题（不能完全解决，因为理论上，当打开文件、连接等等足够多时，迟早会耗尽，一般来说不管是做代理还是做网站，这个操作都是必须的）。\n\n- **临时提高**（重启后恢复为 1024）\n```shell\nulimit -n 65535\n```\n\n- **永久提高**（重启后依然为 65535，当然打开文件后手动删除就恢复了）\n```shell\necho \"* soft nofile 65535\n* hard nofile 65535\nroot soft nofile 65535\nroot hard nofile 65535\" \u003e\u003e /etc/security/limits.conf\n```\n\n执行以上命令后，需要重启 SNIProxy 来使其生效，如果还不行请尝试重启系统。\n\n```yaml\nsystemctl restart sniproxy\n```\n\n\u003c/details\u003e\n\n****\n\n## 问题反馈\n\n如果你遇到什么问题，可以先去 [**Issues**](https://github.com/XIU2/SNIProxy/issues)、[Discussions](https://github.com/XIU2/SNIProxy/discussions) 里看看是否有别人问过了（记得去看下  [**Closed**](https://github.com/XIU2/SNIProxy/issues?q=is%3Aissue+is%3Aclosed) 的）。  \n如果没找到类似问题，请新开个 [**Issues**](https://github.com/XIU2/SNIProxy/issues/new) 来告诉我！\n\n\u003e [!NOTE]\n\u003e _与 `反馈问题、功能建议` 无关的，请前往项目内部 论坛 讨论（上面的 `💬 Discussions`_  \n\n****\n\n## 赞赏支持\n\n![微信赞赏](https://github.com/XIU2/XIU2/blob/master/img/zs-01.png)![支付宝赞赏](https://github.com/XIU2/XIU2/blob/master/img/zs-02.png)\n\n****\n\n\n## 手动编译\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003ccode\u003e\u003cstrong\u003e「 点击展开 查看内容 」\u003c/strong\u003e\u003c/code\u003e\u003c/summary\u003e\n\n****\n\n为了方便，我是在编译的时候将版本号写入代码中的 version 变量，因此你手动编译时，需要像下面这样在 `go build` 命令后面加上 `-ldflags` 参数来指定版本号：\n\n```bash\ngo build -ldflags \"-s -w -X main.version=v1.0.4\"\n# 在 SNIProxy 目录中通过命令行（例如 CMD、Bat 脚本）运行该命令，即可编译一个可在和当前设备同样系统、位数、架构的环境下运行的二进制程序（Go 会自动检测你的系统位数、架构）且版本号为 v1.0.4\n```\n\n如果想要在 Windows 64位系统下编译**其他系统、架构、位数**，那么需要指定 **GOOS** 和 **GOARCH** 变量。\n\n例如在 Windows 系统下编译一个适用于 **Linux 系统 amd 架构 64 位**的二进制程序：\n\n```bat\nSET GOOS=linux\nSET GOARCH=amd64\ngo build -ldflags \"-s -w -X main.version=v1.0.4\"\n```\n\n例如在 Linux 系统下编译一个适用于 **Windows 系统 amd 架构 32 位**的二进制程序：\n\n```bash\nGOOS=windows\nGOARCH=386\ngo build -ldflags \"-s -w -X main.version=v1.0.4\"\n```\n\n\u003e 可以运行 `go tool dist list` 来查看当前 Go 版本支持编译哪些组合。\n\n****\n\n当然，为了方便批量编译，我会专门指定一个变量为版本号，后续编译直接调用该版本号变量即可。  \n同时，批量编译的话，还需要分开放到不同文件夹才行（或者文件名不同），需要加上 `-o` 参数指定。\n\n```bat\n:: Windows 系统下是这样：\nSET version=v1.0.4\nSET GOOS=linux\nSET GOARCH=amd64\ngo build -o Releases\\sniproxy_linux_amd64\\sniproxy -ldflags \"-s -w -X main.version=%version%\"\n```\n\n```bash\n# Linux 系统下是这样：\nversion=v1.0.4\nGOOS=windows\nGOARCH=386\ngo build -o Releases/sniproxy_windows_386/sniproxy.exe -ldflags \"-s -w -X main.version=${version}\"\n```\n\n\u003c/details\u003e\n\n****\n\n## Credit\n\nThe source code has been adapted from [FastGitORG/F-Proxy-Agent](https://github.com/FastGitORG/F-Proxy-Agent) and [TachibanaSuzume/SNIProxyGo](https://github.com/TachibanaSuzume/SNIProxyGo) .  \n\nThank them for their help!\n\n****\n\n## License\n\nThe GPL-3.0 License.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiu2%2Fsniproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fxiu2%2Fsniproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fxiu2%2Fsniproxy/lists"}