在 多线接入 (电信、联通) 的网络环境下, 如何科学地进行分流一直是个令人头疼的问题。
各种方案都有各自的优缺点, 并不存在 “完美” 的解决方案。这里我分享一种更贴合国内环境、相对实用的方案。
常见家用分流方案
静态路由表分流 Layer 3
最常见的做法是导入 ChinaIP 地址列表, 采用 “取反” 的方式: 国内流量直连 (电信走电信、联通走联通), 其余海外流量走隧道。这也被称为大陆白名单模式。
常见方式包括:
-
直接导入 ChinaIP.txt
- 做法: 下载并导入
ChinaIP.txt
地址列表 - 缺点:
- 需要不定期手动更新路由表
- 项目死的快, 容易失效
- 做法: 下载并导入
-
主路由定时更新 ChinaIP.txt
- 做法: 在主路由上定时执行脚本, 下载并更新
ChinaIP.txt
- 缺点:
- 更新时需全量删除并重新加载地址表, 过程较慢
- 更新过程中连接会短暂中断
- 做法: 在主路由上定时执行脚本, 下载并更新
-
旁路由 + OSPF 热更新 + 脚本每日更新
- 做法: 在旁路由上通过 OSPF 协议实现路由表热更新, 并用脚本每天自动更新
ChinaIP.txt
- 优点: 在三种方式中相对最佳, 能自动化热更新
- 缺点: OSPF 仅适用于局域网, 若直接与 VPS 建立 Peer, 会导致严重卡顿
- 做法: 在旁路由上通过 OSPF 协议实现路由表热更新, 并用脚本每天自动更新
域名表分流 Layer 7
通过域名表来分流, 仅代理特定域名的流量。
- 优点: 逻辑清晰, 直接按域名分流
- 缺点: 每个设备都需要部署客户端 (如 V2Ray、Clash、Shadowrocket 等), 而一些设备 (如 Apple TV、HomePod) 不支持安装应用, 设备多了之后维护很麻烦
传统方案的三大通病
无论是基于 静态路由表 还是 域名表, 都有以下共同缺陷:
-
没人维护
- 路由表、域名表都需要维护。通常做这类免费项目的人大多都是 “三分钟热度”, 后续更新是个问题
-
更新延迟
- ISP & IDC 的 IP 段调整不会实时同步
- 即使是最勤快的项目, 用脚本从 bgp.he.net 抓取数据, 也只能做到 1 天 1 更, 而 HE 的数据本身就有约 24 小时延后。
-
分类粗糙
- 路由表通常只能细化到 “国家级别”
- 少部分项目会提供主流 ASN 的 IP Range, 但很难保证每日更新全部 ASN
最终会造成流量浪费, 甚至让 “加速器” 变成 “减速器”, 这样的 Debuff 效果。
BGP Take Me Home: BGP 路由表分流
在前文中我们分析了基于静态路由和域名嗅探的分流方案, 它们虽然常见, 但在更新延迟、分类粗糙、没人维护 等方面存在硬伤。
为了解决这些问题, 可以采用 BGP 路由表 分流。
- 优势: 可通过上游实时获取最新的路由表。一旦某个 ASN 的 IP 宣告发生变化, 几秒钟内即可同步更新。
- 精度: 基于 ASN 的分流比基于国家或域名的方式精确得多。
- 拓展玩法: 一些丧心病狂的 BGPlayer 甚至会在同一 ASN 内, 根据 GeoIP 打上 Community 标签, 实现更细粒度的 “二次分流”
这次打算做成 白名单出海 模式:
- 从上游收到全表 (IPv4 约 98 万条)
- 家里的 RouterOS 建立 BGP Peering
- 基于 ASN 与特定 IP 段过滤得到「要出海的 IP」列表
- 改写网关指向海外网关, 并将其导入主路由表。
前提条件: 如何收表
说了那么多… 既然要基于 BGP 分流, 首先需要把 “表” 收回家。常见方法有两类
方法一: 自己动手丰衣足食
如果你愿意自己折腾, 可以直接从 VPS 厂商获取 BGP session。
最方便、门槛最低的选择是 Vultr:
- 创建一个 VPS, 然后提交工单开通能收全表 BGP session
- 使用 Bird 2 收全表, 即使是最低配置的 1 核 0.5GB VPS 也能胜任
- 如果没有 RIR 分配的 ASN, 可以直接使用 Private ASN 建立会话
具体步骤:
- 租一个
/48
的 IPv6 段 (约 5-10 欧元/月) - 找 Vultr 代广播这个 IPv6 段, 并开通 BGP session 功能
- 部署 BGP 路由软件收表:
- RouterOS v7 CHR: 收 IPv4+IPv6 全表时, CPU 使用率长期占用 68% (6 美元/月)
- Bird 2: 最低配置 VPS (3.5 美元/月) 即可轻松收下 IPv4+IPv6 全表
没错开通 BGP session 后, 你可以直接从 Vultr 收到完整的 IPv4 和 IPv6 路由表。不需要自己拥有 ASN, 只需把 IP 挂靠在 Vultr 的 ASN 下即可。
方法二: 抱大腿
如果不想自己折腾, 也可以走 “社交路线”:
-
在 Telegram 群里寻找愿意互联的玩家, 建立 Peer
- 屁股里夹着 5 毛硬币, 在 TG 群里高声呼喊
“我就是那个要和你们 Peer 的网友!” 🤣
- 屁股里夹着 5 毛硬币, 在 TG 群里高声呼喊
-
或者直接和作者 PY, 请求分享路由表
收表其实并不难, 只需要使用 BGP 保留的 私有 ASN:
- 16 位: 64512 - 65534
- 32 位: 4200000000 - 4294967294
这类 ASN 就像内网保留 IP 段一样, 可以在私下尽情使用。把上游收来的全表重分布到本地私有 ASN 就可以了。
收表与配置
首先, 在 VPS 上使用 CentOS 7 + Bird 2 搭建环境。先与 Vultr 建立 IPv4 的 BGP 会话, 从 Vultr 接收完整的路由表。由于 Vultr 自带路由过滤策略, 因此不必担心会收到 bogon 地址或异常路由条目。
同时, 在 VPS 上再建立一个 BGP 会话, 用于连接家里的 RouterOS, 并将接收到的完整路由表导出给本地路由器。这样, 家里的 RouterOS 就能通过 VPS 获得全表, 而无需直接与上游运营商建立会话。
示例 Bird 2 配置
log syslog all;
router id 100.101.102.103;
ipv4 table bgp4;
protocol device {}
protocol direct {}
protocol static {}
protocol bgp TRANSIT_V4 {
description "AceSheep BGP New Jersey";
local as 123456;
hold time 90;
graceful restart;
multihop 2;
password "1522zzwlwlbb";
source address 100.101.102.103;
neighbor 169.254.169.254 as 64515;
ipv4 {
table bgp4;
import all;
export none;
};
}
protocol bgp PEER_HOME {
description "Country Road Take Me Home";
local as 65500;
graceful restart;
multihop 2;
password "1522zzwlwlbb";
source address 172.16.0.1;
neighbor 172.16.0.2 as 65500;
ipv4 {
table bgp4;
import none;
export all;
};
}
建立隧道
由于家宽公网 IP 大多是动态的, 而 BGP 需要固定 IP, 所以通常不能直接和 Vultr 建立 BGP。更重要的是, GFW 会拦截 BGP 协议。
因此需要先建立一个隧道, 把家里的 ROS 和 VPS 拉到同一个 “虚拟局域网” 里, 常见选择:
- IPSec
- GRE
- WireGuard
- ZeroTier
隧道建立好后, 再通过隧道连接 BGP
RouterOS 配置流程
在 VPS 上成功收取全表并准备好 BGP 转发后, 接下来需要让家里的 RouterOS 与 VPS 建立 BGP 会话, 通过 VPS 中转, 将完整的 IPv4 路由表同步到家里的路由器。
建立过滤规则
在配置 BGP 时, 合理的过滤规则非常重要。它不仅可以避免无用路由的引入, 也能防止错误的路由被发布出去, 从而确保网络的稳定与安全。
我们采用 默认拒绝、逐步放行 的过滤思路。默认情况下导入和导出均不允许任何路由, 然后再根据需要逐步放行。这样可以避免误操作导致的全表泛滥。
进入 Routing -> Filters 界面, 新建导入与导出规则。
因此我们先新建两个空规则: BGP-HOME-IN
(导入规则) 和 BGP-HOME-OUT
(导出规则)。初始状态下, 两者都直接丢弃所有路由, 确保没有未经过滤的路由被引入或发布。
新建导入规则, BGP-HOME-IN
新建导出规则, BGP-HOME-OUT
这样一来, 可以建立 BGP 会话了, 不会立即交换任何路由。
建立 BGP 实例
在 RouterOS 中, 所有的 BGP 会话都基于实例运行, 因此首先需要新建一个实例
进入 Routing -> BGP, 在 Instances 选项卡中添加一个新的模板。
配置示例
Name: Country Road Take Me Home
AS: 这里使用私有 AS 号, 范围为 64512 - 65535, 可以根据实际情况自选一个。例如本文使用 65500
Router ID: 通常填写路由器的 IPv4 地址, 用于在 BGP 网络中唯一标识
# 默认情况下, 如果一个路由器同时作为多个 BGP Client 的 Route Reflector (RR), 它会在客户端之间转发路由。
# 但在我们的场景中, 路由器只是单纯作为边缘设备, 与上游或下游建立 BGP 会话, 不承担 "路由反射器 (Route Reflector)" 的角色, 那么就不需要在客户端之间反射路由。
# 这样路由器只会处理自己与对等体之间的路由, 不会产生多余的转发。
Client To Client Reflection: 取消勾选
建立 BGP 会话
完成实例配置后, 接下来在 Peers 选项卡中新建一个与 VPS 的 BGP 会话。
进入 Routing -> BGP -> Peers
配置示例
Name: PEER_HOME
Instances: Country Road Take Me Home
Remote address: 172.16.0.2 # 对端 VPS 的隧道内网地址
Remote AS: 65500 # VPS 使用的私有 AS 号, 需要和之前配置一致
TCP MD5 Key: 1522zzwlwlbb # 可选项, 如果双方配置了密码, 这里要保持一致
Hold Time 240
Keepalive: 60
In Filter: BGP-HOME-IN
Out Filter: BGP-HOME-OUT
其中 In Filter 和 Out Filter 的配置非常关键, 避免因为配置失误造成网络环路或路由污染。
- BGP-HOME-IN: 主要作用是决定接收到的路由如何处理
- BGP-HOME-OUT: 主要作用是决定向外部广播哪些路由, 避免把无关或错误的路由扩散到外部
配置完成后, RouterOS 会尝试与 VPS 建立 BGP 会话。一旦邻居关系成功建立, 就能从 VPS 获取完整的 IPv4 路由表, 并根据过滤策略导入到本地路由表中。
策略路由: 分流
一套简单的分流逻辑可以定义为:
- 国内流量
- 联通: 默认网关, 走联通
- 电信 (China Telecom / CHINANET): 电信的流量走电信线路
- 海外流量
- 海外 CDN 服务 (Fastly、Amazon、Cloudflare、Akamai 等): 走 “留学” 通道
- 海外大公司 (Google、Telegram、Netflix、Facebook、Wikipedia、GitHub): 走 “留学” 通道
通过这种方式, 就能把电信和联通两条线路融合起来, 对国内的访问尽量走本地运营商, 减少跨网访问带来的延迟和丢包;同时对海外常用服务进行优化, 让出国流量更顺畅。
分流规则
接下来, 我们需要在 BGP-HOME-IN
过滤器中逐步放行需要的路由。
这里导入的规则作用主要是决定接收到的路由如何处理:
- 是否放行或丢弃特定前缀
- 是否修改下一跳 (Next Hop)
- 是否添加路由注释 (例如标识路由来源)
- 是否检查网关的可达性
在 Route Filter 的 Action 选项卡中, 可以对接收到的路由进行进一步处理:
- Set in Nexthop: 指定下一跳地址 (适用于静态 IP 场景)
- Set in Nexthop Direct: 直接指定出口接口 (如 PPPoE 拨号)
- Set Route Comment: 为路由增加注释, 方便管理
- Set Check Gateway: 启用网关检测, 避免链路异常导致黑洞路由
- Set Routing Mark: 将路由导入到指定的路由表, 然后配合
ip route rule
或mangle
实现策略路由 (例如不同设备/子网走不同出口)。若不设置, 默认 BGP 学到的路由会进入main
表
BGP AS Path 匹配
通过 AS Path 规则可以对特定来源的路由进行精细化控制。
示例规则
含义: 匹配所有以 AS16509 或 AS14618 结尾的路由
_16509$|14618$
编写 AS Path 规则时, 只需要记住几个要点:
- 以
_
开头, 表示匹配 ASN 的边界 - ASN 后面加
$
表示匹配结尾 - 多个 ASN 之间用
|
分隔
这样就能灵活定义需要留学/跨境的海外流量
常用 ASN 参考
为了方便大家快速上手, 我也整理了一份常用 ASN 列表, 覆盖了大部分国内运营商、海外 CDN 以及常见互联网巨头。
# Google
15169
# Google Extra ASNs
396982, 395973, 36492, 36411, 36383, 36040, 19527
# Telegram
62041, 62014, 59930
# Netflix
55095, 40027, 2906
# Akamai
49846, 43639, 393560, 393234, 36183, 35994, 35204, 34164,
33905, 32787, 31984, 31108, 26008, 24319, 21342, 213120,
20940, 200005, 18717, 18680, 17204, 16625, 12222
# Facebook
32934, 63293, 54115
# Wikipedia
14907
# GitHub
36459
# Twitter
13414, 35995, 63179
# Equinix Services
54825
# Fastly
54113
# Amazon (AWS)
16509, 14618
# EdgeCast
15133
# Cloudflare
13335
# ChinaNet / CHINANET (骨干网 / 电信 CN2 等)
4810, 4811, 4812, 4816, 4835, 4134, 44218, 17998, 36678,
63810 - 63825, 59300 - 59391, 59223 - 59299, 58769 - 58776,
58563 - 58574, 58466, 58461, 58517, 58518, 58539 - 58543,
136188 - 136200, 134756 - 134775, 134238, 133774 - 133776,
132225, 132437, 132833, 131325, 139015, 139587, 139586,
139585, 139767, 140083, 140527, 140636, 140638, 140903,
141006, 141025, 141679, 141739, 141771, 141998, 142404,
142608, 146966, 147038, 148969, 148981, 149178, 149837,
149839, 149979, 150145, 151058, 151185, 151397, 151628,
151823
需要注意的是, RouterOS 的 Route Filter Chain 是从上往下依次执行的, 遇到匹配规则后就会生效, 因此要合理安排规则顺序。
BGP Take Me Home, 让分流真正做到科学、实时、个性化
科普
路由器的选路原则
在路由器中, 路由表 (Main 表) 里可能会同时存在多种来源的路由, 比如直连路由、静态路由、BGP、OSPF 等。
当多条路由指向同一个目标网段时, 路由器就需要进行 “选路”。
不同路由协议的优先级由 distance (管理距离) 来决定, 常见的默认值如下
协议 | distance |
---|---|
直连路由 | 0 |
静态路由 | 1 |
eBGP | 20 |
OSPF | 110 |
RIP | 120 |
MME | 130 |
iBGP | 200 |
路由器的具体选路逻辑
路由器在选择路由时, 通常遵循以下规则:
- 最长前缀优先
- 子网掩码越大 (网络范围越小), 路由越 “精确”, 优先级就越高。
- 比如同时存在
1.1.1.0/24
和1.1.1.0/25
, 无论 distance 设置多少, 都会优先选择更具体的/25
路由。
- 比较 distance
- 如果前缀长度相同, 才会比较各路由的 distance 值, 数值越小越优先。
- 例如静态路由 (distance 1) 会覆盖 eBGP (distance 20) 的路径。
- 负载均衡/ECMP
- 当多条路由前缀与 distance 都一致时, 路由器可能会启用 ECMP (等价多路径), 把流量分摊到多条路径上。
举个例子
假设你通过 iBGP 收到了一条 1.1.1.0/24
的路由, 并且在 Filter 中统一设置了它的出口走 电信链路
但是, 你希望这条流量改走另一个出口 (比如联通), 该怎么做呢?
解决办法就是添加一条静态路由:
- 指定
1.1.1.0/24
的下一跳为联通出口 - 由于静态路由的 distance 默认为 1, 比 iBGP 的 200 更优先
- 最终路由器会选择你配置的静态路由来转发数据
这样就能 “强制” 覆盖 BGP 下发的路径, 实现更灵活的路由控制。
原文
Mikrotik 通过ASN分流
在家也要玩BGP 之 Mikrotik Fan Boy版
在家也要玩BGP(1):简单的多运营商接入策略路由配置
家用垃圾网络 · 软路由启动
在家也要玩BGP(1.5):我的双线分流规则