ICTSC2025 本戦 問題解説: [3061] ネットワークって難しいね
問題文
概要
冗長構成のルーター(vyos-1, vyos-2)を構築し、バックエンドのサーバーとの間でBGPピアリングを完了させました。しかし、クライアントからサーバーのVIP(172.16.61.100)へPingを実行しても、全く応答がありません。 通信が正常に行えるように復旧させてください。

制約
- ファイアウォールのルール(set firewall 階層)を変更・削除してはならない。(セキュリティ要件のため)
- Static Routeを新たに追加してはならない。
- VRRPの優先度(Priority)を変更し、Master/Backupを切り替えてはならない(vyos-2がMasterのままとすること)。
- server及びclientの設定は一切変更してはならない。
- 送信元IPアドレスの変換(Source NAT / Masquerade等)を行ってはならない。
- 両vyosサーバ共にreboot後も終了状態が維持されていること
初期状態
- clientから
ping 172.16.61.100を実行すると、100%パケットロスとなり通信が成立しない。
終了状態
-
clientから
ping 172.16.61.100を実行すると、Echo Replyが正常に返り、パケットロスが0%となる。 -
`vyos-2 をダウンさせた状態においても、clientからserver(172.16.61.100)へのPing通信が成立すること。
解説
-
ルーティングの破綻(AD値の逆転)の特定と修正
初期状態では、VIPへのPingが vyos-2 に到達した後、迷子になっています。vyos-1 のルーティングテーブルを確認すると、BGPで学習すべきVIP(172.16.61.100/32)の経路が、vyos-2 からOSPF経由で流れてきた経路によって上書きされています。これはVyOSにおけるAD値が OSPF (110) < iBGP (200) と評価されるためです。
これを解消するため、VIPの経路がOSPFへ再配布されないようにプレフィックスリストとルートマップを作成し、両方のルーターの redistribute bgp に適用する必要があります。 -
非対称ルーティングとステートフルFWの競合解決
経路のループを解消しても、Pingは通りません。パケットキャプチャやFWのログ(Rule 20: invalid)を確認すると、戻りパケットが vyos-1 で破棄されていることがわかります。
行きのパケットはVRRP Masterである vyos-2 を通りますが、サーバー側はBGPのタイブレーカー(ルータIDが若い順)に従い、戻り経路として vyos-1 を選択します。これにより非対称ルーティングが発生し、行きのセッション情報を持たない vyos-1 のFWがパケットを不正とみなしてDropしています。
解決策として、FWのルールを削除するのではなく、vyos-1 側のBGP経路広報時にMetric(MED)を悪化させ、サーバーに vyos-2 を選ばせるトラフィックエンジニアリングを行うのが正攻法です。
また、この問題は制作者が想定していたトラブルではなく、天然でできたトラブルのため、解法が複数存在する可能性があります。
想定解法
正攻法を下記に残してあります。
まずclientから ping 172.16.61.100を送信します。すると
root@3061-client:/home/ictsc# ping 172.16.61.100
PING 172.16.61.100 (172.16.61.100) 56(84) bytes of data.
^C
--- 172.16.61.100 ping statistics ---
3 packets transmitted, 0 received, 100% packet loss, time 2033ms
という結果になり通らないことが確認できます。
次に、tracerouteを実行します
ictsc@3061-client:~$ traceroute 172.16.61.100
traceroute to 172.16.61.100 (172.16.61.100), 30 hops max, 60 byte packets
1 10.0.61.3 (10.0.61.3) 0.811 ms 0.728 ms 0.631 ms
2 * * *
3 * * *
4 * * *
5 * * *
6 * * *
7 *
以下略
という結果が返ってくるため、vyos-2へ届いていることは確認できます。
消失したパケットの行方を知るため、vyos-2へログインします。
こちらで調査のため、 show ip route 172.16.61.100 を実行しますが、
ictsc@3061-vyos-2:~$ show ip route 172.16.61.100
Routing entry for 172.16.61.100/32
Known via "bgp", distance 200, metric 0, best
Last update 00:26:49 ago
* 172.16.61.1, via eth1, weight 1
という結果になり、異常はみられません。ここで、冗長構成を組んでいるvyos-1へログインし、調査します
ictsc@3061-vyos-1:~$ show ip route 172.16.61.100
Routing entry for 172.16.61.100/32
Known via "ospf", distance 110, metric 20, best
Last update 00:28:18 ago
* 10.0.61.3, via eth2, weight 1
この結果から、BGPで直接学習すべきVIPの経路が、vyos-2 から流れてきたOSPF経路によって上書きされている現状に気づけます。両ルーターの再配布設定を見に行きます。
ictsc@3061-vyos-1:~$ configure
[edit]
ictsc@3061-vyos-1# show protocols ospf
area 0 {
network 10.0.61.0/24
}
redistribute {
}
ictsc@3061-vyos-2:~$ configure
[edit]
ictsc@3061-vyos-2# show protocols ospf
area 0 {
network 10.0.61.0/24
}
redistribute {
bgp {
}
}
この結果から、vyos-1はそもそも redistribute bgpの設定がなく、vyos-2は設定自体はあるが、ルートマップが適用されていないことが確認できます。
vyos-2 がフィルタ無しで再配布しているため、VIPの経路までvyos-1へ流れ込み、AD値の逆転を引き起こしていること、vyos-1 に再配布設定が入っていないのは、冗長構成の設計として明らかに設定漏れです。
これを修正するために、VIPを除外するフィルタを作成し、vyos-2の既存設定を修正するとともに、vyos-1には欠落していた設定を正しく追加します。
-
vyos-1
configure set policy prefix-list FILTER-VIP rule 10 action 'deny' set policy prefix-list FILTER-VIP rule 10 prefix '172.16.61.100/32' set policy prefix-list FILTER-VIP rule 20 action permit set policy prefix-list FILTER-VIP rule 20 prefix 0.0.0.0/0 set policy prefix-list FILTER-VIP rule 20 le 32 set policy route-map RMAP-BGP-TO-OSPF rule 10 action permit set policy route-map RMAP-BGP-TO-OSPF rule 10 match ip address prefix-list 'FILTER-VIP' # 欠落していた再配布設定をフィルタ付きで追加 set protocols ospf redistribute bgp route-map 'RMAP-BGP-TO-OSPF' commit save exit -
vyos-2
configure set policy prefix-list FILTER-VIP rule 10 action 'deny' set policy prefix-list FILTER-VIP rule 10 prefix '172.16.61.100/32' set policy prefix-list FILTER-VIP rule 20 action permit set policy prefix-list FILTER-VIP rule 20 prefix 0.0.0.0/0 set policy prefix-list FILTER-VIP rule 20 le 32 set policy route-map RMAP-BGP-TO-OSPF rule 10 action permit set policy route-map RMAP-BGP-TO-OSPF rule 10 match ip address prefix-list 'FILTER-VIP' # 既存の再配布にフィルタを適用 set protocols ospf redistribute bgp route-map 'RMAP-BGP-TO-OSPF' commit save exit
確認のため、 show ip route 172.16.61.100 コマンドで、両ルーターが正しく直接サーバを向いているか確認します
ictsc@3061-vyos-1:~$ show ip route 172.16.61.100
Routing entry for 172.16.61.100/32
Known via "bgp", distance 200, metric 0, best
Last update 00:06:50 ago
* 172.16.61.1, via eth1, weight 1
ictsc@3061-vyos-2:~$ show ip route 172.16.61.100
Routing entry for 172.16.61.100/32
Known via "bgp", distance 200, metric 0, best
Last update 00:46:58 ago
* 172.16.61.1, via eth1, weight 1
ここでclientから ping 172.16.61.100を実行してみます
ictsc@3061-client:~$ ping 172.16.61.100
PING 172.16.61.100 (172.16.61.100) 56(84) bytes of data.
^C
--- 172.16.61.100 ping statistics ---
2 packets transmitted, 0 received, 100% packet loss, time 1006ms
まだこの時点では通りません。
再度tracerouteを実行します
ictsc@3061-client:~$ traceroute 172.16.61.100
traceroute to 172.16.61.100 (172.16.61.100), 30 hops max, 60 byte packets
1 10.0.61.3 (10.0.61.3) 0.753 ms 0.639 ms 0.563 ms
2 * * *
3 * * *
4 * * *
5 * * *
ルーティングテーブルは直したのにも関わらず、パケットが通らないので、パケットをキャプチャします
clientからpingを送信した状態でvyos-2のeth1にて、 monitor traffic interface eth1 コマンドで確認します。
ictsc@3061-vyos-2:~$ monitor traffic interface eth1
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:49:20.768803 IP 10.0.61.1 > 172.16.61.100: ICMP echo request, id 3242, seq 17, length 64
02:49:21.792523 IP 10.0.61.1 > 172.16.61.100: ICMP echo request, id 3242, seq 18, length 64
02:49:22.816829 IP 10.0.61.1 > 172.16.61.100: ICMP echo request, id 3242, seq 19, length 64
02:49:23.840766 IP 10.0.61.1 > 172.16.61.100: ICMP echo request, id 3242, seq 20, length 64
リクエストは届いているが、リプライが確認できないのでvyos-1も確認します(monitor traffic interface eth1)
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth1, link-type EN10MB (Ethernet), snapshot length 262144 bytes
02:57:55.373199 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 1, length 64
02:57:56.417441 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 2, length 64
02:57:57.441481 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 3, length 64
02:57:58.465696 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 4, length 64
02:57:59.489809 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 5, length 64
02:58:00.513940 IP 172.16.61.100 > 10.0.61.1: ICMP echo reply, id 3250, seq 6, length 64
こちらに届いていることが確認できます。
このことからvyos-1でパケットが破棄されていることがわかります。
パケットを破棄している理由をファイヤウォールを確認して証明します
ictsc@3061-vyos-1:~$ show firewall ipv4 forward filter
Ruleset Information
---------------------------------
ipv4 Firewall "forward filter"
Rule Action Protocol Packets Bytes Conditions
------- -------- ---------- --------- ------- -----------------------------------------
10 accept all 12 1044 ct state { established, related } accept
20 drop all 98 8424 ct state invalid
30 accept all 144 9000 iifname "eth2" accept
default drop all 0 0
client側からpingを送れば送るほど、Rule20のPacketsが増えることが確認できます。
ictsc@3061-vyos-1:~$ show firewall ipv4 forward filter
Ruleset Information
---------------------------------
ipv4 Firewall "forward filter"
Rule Action Protocol Packets Bytes Conditions
------- -------- ---------- --------- ------- -----------------------------------------
10 accept all 12 1044 ct state { established, related } accept
20 drop all 100 8592 ct state invalid
30 accept all 144 9000 iifname "eth2" accept
default drop all 0 0
原因が非対称ルーティングであると証明されたため、サーバからの戻りパケットを行きと同じvyos-2へ向かわせるよう、vyos-1に入りBGPの経路属性を操作します。
configure
# vyos-1からサーバへ広報する経路のMetric(MED)を100に設定
set policy route-map RMAP-BGP-OUT rule 10 action permit
set policy route-map RMAP-BGP-OUT rule 10 set metric 100
# サーバ(172.16.61.1)への送信(export)ポリシーとして適用
set protocols bgp neighbor 172.16.61.1 address-family ipv4-unicast route-map export RMAP-BGP-OUT
compare
commit
save
exit
この設定完了後、clientにて ping 172.16.61.100 を実行します。
ictsc@3061-client:~$ ping 172.16.61.100
PING 172.16.61.100 (172.16.61.100) 56(84) bytes of data.
64 bytes from 172.16.61.100: icmp_seq=1 ttl=63 time=1.81 ms
64 bytes from 172.16.61.100: icmp_seq=2 ttl=63 time=1.22 ms
64 bytes from 172.16.61.100: icmp_seq=3 ttl=63 time=1.02 ms
^C
--- 172.16.61.100 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2003ms
rtt min/avg/max/mdev = 1.021/1.350/1.805/0.332 ms
採点基準
-
clientからVIP(172.16.61.100)へのPingが成功していること。: 50%
-
vyos-2 をダウンさせた状態においても、clientからserver(172.16.61.100)へのPing通信が成立すること。: 50%
注意点
- 制約に則っていなければ0点
講評
解法が色々あって自分が逆に勉強になったなーと思った問題でした。
もっと制約等で厳しくすべきだと考えました。