Skip to content

OSPF (过期) 2023 年 6 月

前言

建 dn11 的时候遇到了一些小问题,在 fullmesh 的网络拓扑的情况下偶尔会出现几个节点连不上的情况,连不上了就直接连不上了,没有后话了。

实际上是可以通过绕路的方式连通的,这就要引入一些路由协议了,最早的构想是引入 BGP 协议的但是考虑了一下觉得这些东西的体量还是太大了,最后决定引入 OSPF 协议。

下面将在 openwrt 上使用 bird2 配置 OSPF over WireGuard。

OSPF 配置

作为示例,本文选择 bird2 提供 OSPF 支持,先安装 bird2

shell
opkg install bird2
opkg install birc2c

在 openwrt 上,bird2 的配置文件默认地址在 /etc/bird.conf

bird2 的默认配置文件很长,算是一个 all config 先给他放到一边去

shell
mv /etc/bird.conf /etc/bird.conf.bak

然后我们新建一个自己的 bird.conf

shell
vim /etc/bird.conf

给各位准备了配置文件模板,粘贴进去再改改就好了

nginx
log syslog all;
debug protocols all;

router id 172.16.255.4;

protocol device{
}

protocol kernel{
    ipv4 {
        export where proto = "wg";
    };
}

protocol ospf v2 wg {
    ipv4 {
        export all;
        import where net !~ 172.16.4.0/24;
    };
    area 0.0.0.0 {
        interface "wg*" {
            cost 5;
        };
    };
    area 0.0.0.4 {
        interface "br-lan";
    };
}
  • 每个路由设备的 route id 都是唯一的, route id 本质上是一个 int32, 只是为了方便使用被 . 分割成了四段,需要提前约定。一般来说为了方便记忆和配置,会取了一个网段将这个网段下的 ip 对应的 int 作为 route id ,dn11 对于 route id 有规范,起始 id 为 172.16.255.1 ,请在文档中按顺序往下申请
  • import where net !~ 172.16.4.0/24; 这一行指定的网段的路由不会从 ospf 中学习,一般需要把这里配置成你的 lan 的网段,因为 lan 的路由早已由系统定义,不需要也不能由 ospf 来指定
  • export all; 这一行指定了由 ospf 导出给其他路由学习的网段,如果你由 ospf 管理的接口中有不愿意导出的网段可以修改这里,这里导出全部
  • 后面紧跟着两个 area,每个 area 也有自己的 id,这两个 id 和 route id 一样仅仅是一个 int32 并不代表任何网络含义,仅仅是个名字, 0.0.0.0 是骨干 area ,在这里必须统一使用 area 0.0.0.0
  • 在下一行我们用 interface "wg*" 指定了一些接口,这里的 * 是通配符,这种写法指定了所有名字以 wg 开头的接口在这个 area 内,后续建立 wg 接口的时候要遵循这里的配置,如果你想使用其他名称也可以修改这里的配置
  • 在下一行,指定了一个 cost ,事实上即使不配置 cost ospf 也会自动地指定一个 cost,cost 默认的值为 100Mbps / 连接速度
  • area 0.0.0.4 用于你的 lan, dn11 目前定义每个人的 lan 都单独占用一个 area, 因此,需要一个唯一的 area 用于 lan, 请在文档中申请
  • 下一行的 interface 里指定了 lan 接口,对于 openwrt 旁路由,这里一般就是 br-lan,主路由一般就是 lan

TIP

需要在文档中申请的有 route id 和 area id

编辑完配置文件后,就可以启动 bird2 了

shell
service bird start

WireGuard 配置

下面建立 WireGuard 点对点连接,均在 openwrt 的 web 页面里操作

在要建立 WireGuard 连接的两个路由上要进行相对应的操作,操作的流程一致

新建接口

网络-接口-添加新接口... 中新建一个 WireGuard 接口,以 wg* 的格式命名,作为示例,这里新建一个 wg0add_interface

配置 WireGuard 接口

  • 私钥填写你自己的私钥,如果没有,可以使用 wg genkey 命令生成一个
  • 监听端口最好使用一个比较高的端口,可以随意指定,但是不同的 WireGuard 接口监听的端口不能重复
  • IP 地址是 WireGuard 隧道中你的 IP 地址,dn11 对 WireGuard 隧道地址有规范,起始地址为 172.16.128.0 ,每个人每次可以在文档中申请一个 /28 的网段,而每次使用一个 /32,例如 172.16.128.16/32

TIP

记住这个值,在配置静态路由时会使用,也需要交换给对方

先保存上述配置,点击 连接 重连该 WireGuard 接口,此时接口公钥可以在 状态-WireGuard状态 里获取,下面继续配置这个接口,先添加一个 peer

  • 公钥是建立点对点 WireGuard 连接的对方的公钥,对方在完成上述配置后就能获取到接口公钥,将对方的公钥填写在这里
  • 允许的 IP 填写 0.0.0.0/0 让 WireGuard 放通所有流量(如果你真的不想填这个,可以填你要访问的网段和组播地址,不推荐)
  • 路由允许的 IP 不要勾选,路由将由 OSPF 管理,不要让 WireGuard 来配置路由
  • 端点主机填对方主机地址,请事先配置好 DDNS
  • 端点端口填对方的 WireGuard 监听地址
  • 持续 Keep-Alive 仅当你的路由位于 nat 后,对方无法直连时勾选

    INFO

    实际上 OSPF 的组播包和路由交换会产生流量,一点程度会起到和 Keep-Alive 类似的作用

配置完成后保存

config_interface

配置防火墙

对于 dn11 老成员,只需将这个新建的 WireGuard 接口分配到原先用于 WireGuard 的防火墙区域即可,然后就可以跳过这一步

没有配置过的话需要在 WireGuard 接口的配置中修改防火墙设置为 “不指定或新建”,然后填写新的防火墙区域名称,保存配置,以创建一个新的防火墙区域

接下来转到 网络-防火墙 ,配置新建的防火墙区域。基本设置中,入站出站转发均改为接受,端口触发中,lan 到 WireGuard 接口和 WireGuard 接口到 lan 的转发均改为接受,保存并应用

配置静态路由

Why?

由于没有让 WireGuard 配置路由,在隧道 IP 地址中又选取了 /32 的网段,对端隧道 IP 和自己并不在一个子网,以至于没有到对面的隧道地址的路由,这才需要手动配置静态路由。

/etc/bird.conf 里的 static 协议里静态路由配置,示例如下:

nginx
protocol static {
    ipv4 {
        import all;
        export none;
    };
    route 172.16.128.2/32 via "wg0";
  • 172.16.128.2/32 应填写对端隧道 IP/32
  • wg0 应该填写为隧道网卡名称

这些配置在 static 协议里指定了到对端隧道 IP 的路由,然后将这些路由从 static 协议里 import 到 bird

现在恭喜你完成了所有配置,没有意外的话稍等片刻应该就能访问到对面的网络了

如果仍然无法访问请转到故障排查

连接到更多路由

对每一个连接都需要一个独立的 WireGuard 接口,每个接口都会存在于一个独立的 WireGuard 子网。因此需要新建一个 WireGuard 接口来连接到第二个路由(比如说 wg1 )

  1. 配置 WireGuard

    与配置第一个 WireGuard 接口无异,注意监听端口和 IP 地址不能和其他接口重复

  2. 配置静态路由

    与配置第一个静态路由无异,注意网关和目标地址不能和前一个重复,且与 WireGuard 配置里的 IP 保持一致

WARNING

1. 仔细检查端口是否重复

2. 不要忘了在配置完成后重连接口

故障排查

排查步骤

  1. 检查 WireGuard 连接是否连上,查看 “状态 - WireGuard 状态” 中对应接口的对端是否成功握手,图标是否亮起,如果没有说明 WireGuard 有问题
  2. 检查 OSPF 是否连上,查看 “状态 - 系统日志”,拉到最新,如果 OSPF 卡在 Init 状态,说明静态路由配置有问题
  3. 上面两项都过了之后应该能 ping 通对面的路由,否则就是疑难杂症
  4. 能 ping 通对面路由但是 ping 不通对面 lan 的主机,转到配置防火墙

FAQ

  • Q: 没有公网 IPv4 能不能用 IPv6

    A: 可以,两边端点主机的 DDNS 都要做 AAAA 解析,不要上 A 解析,其他配置依然使用 IPv4

参考文档

Made with ❤️ by DN11 team