Vultr BGP 收全表的正確姿勢

前言

許多 BGP 玩家開始旅程的第一步,就是使用 Vultr 來建立 BGP 連線。隨著越來越多玩家的加入,也聽到了許多人詢問了一些問題,而這些問題大致上都相同,因此在這篇文章整理出來。

官方文件

在 Vultr 官方文件的寫法是這樣的:

router id 203.0.113.123;

protocol bgp vultr {
    # substitute with your AS or Vultr's private AS
    local as 64512;
    source address 203.0.113.123;
    import none;
    export all;
    graceful restart on;
    multihop 2;
    neighbor 169.254.169.254 as 64515;
    password "hunter2";
}

我們可以看到,由於這裡是 import none; 也就是不收表的意思,這麼使用的話就只會單純使用機器原本的 ::/0 路由到 Vultr,也是沒有問題的做法。

但悲劇的開始,就是當你想要收表並放進 Kernel 的時候,一切的悲劇就會開始了。

異常的開始

當你改成類似下面的配置後,你會開始注意到你的 Session 發生一些怪事。

protocol kernel {
    scan time 15;
    ipv6 {
        import all;
        export all;
    };
}

protocol bgp vultr {
    ipv6 {
        import all;
        export filter YourFilter;
    };
    local 2001:19f0:4400::1 as 64512;
    neighbor 2001:19f0:ffff::1 as 64515;
    password "hunter2";
    multihop 2;
    graceful restart on;
}

不斷斷線

你可能會開始注意到,你的 Session 收沒多少路由就開始斷線,重新連線後一樣的事情繼續發生。

001.jpg

路由不可達

當你使用 show route table master6 時,你會發現收到的路由全部出現 unreachable。

002.jpg

AS Path 錯誤

當你使用 show route all table master6 時,你會發現 AS Path 都以 64515 開頭,這顯然是不正確的。

003.jpg

解決方式

這邊提供了幾個修正方式,照著操作就沒問題了!

修正斷線及路由問題

由於 Vultr 的機器是多跳 (multihop) 才連上他們的 BGP IP 位址,因此我們要加一條 static 規則,將 2001:19f0:ffff::1/128 指向我們的預設閘道。

protocol static {
    ipv6;
    route 2001:19f0:ffff::1/128 via fe80::fc00:4de:6c2b:a31f%enp1s0;
}

而上方的 fe80::fc00:4de:6c2b:a31f 需要修改成你自己的,你可以透過 ip -6 nei 獲取到。透過 birdc c 生效後,你應該可以看到這些都變得正常了。

004.jpg

修正 AS Path 問題

由於我們跟 Vultr 起 BGP Session 時,我們是與 AS64515 連線嘛,因此我們會先看到 AS64515 的存在,接下來才會看到 Vultr 正確的 AS20473。

因此我們要修正一下 filter,把這類的 Bogon ASNs 刪除。我們要先定義 Bogon 的 ASN 範圍。

define BOGON_ASNS = [
    0,                      # RFC 7607
    23456,                  # RFC 4893 AS_TRANS
    64496..64511,           # RFC 5398 and documentation/example ASNs
    64512..65534,           # RFC 6996 Private ASNs
    65535,                  # RFC 7300 Last 16 bit ASN
    65536..65551,           # RFC 5398 and documentation/example ASNs
    65552..131071,          # RFC IANA reserved ASNs
    4200000000..4294967294, # RFC 6996 Private ASNs
    4294967295              # RFC 7300 Last 32 bit ASN
];

接著,在 Vultr 的 BGP Session 改成這樣:

protocol bgp vultr {
    ipv6 {
        import filter {
            bgp_path.delete(BOGON_ASNS);
            if bgp_path.first != 20473 then bgp_path.prepend(20473);
            accept;
        };
        export filter YourFilter;
    };
    local 2001:19f0:4400::1 as 64512;
    neighbor 2001:19f0:ffff::1 as 64515;
    password "hunter2";
    multihop 2;
    graceful restart on;
}

透過 birdc c 生效後,你應該就會看到 AS Path 正常囉。

005.jpg