ICTSC2025 本戦 問題解説: [1360] 通ってもいいですか
問題文
概要

あなたは拠点間接続について学ぶため、自宅と友達の家でWireGuardを使ってVPN接続を構築することになりました。 友達の家のサーバは、先輩から譲り受けた環境のIPアドレスだけを書き換えて wg-server として流用し、自宅のサーバは新しく wg-client としてWireGuardの設定を行いました。 しかし、設定を終えてインターフェースを起動したものの、互いの通信は全く確立せず、pingの応答が返ってきません。
制約
- wg-server がListenしているWireGuardのポート番号を変更しないこと。
- 各インターフェースに割り当てられたIPアドレスを変更してはならない。
- WireGuardのインターフェース名を変更してはならない。
- WireGuardの設定ファイルを新規作成してはならない。
- 両サーバ共にreboot後も終了状態が維持されていること。
初期状態
-
wg-client からping 10.0.8.1を実行しても応答がない。
-
wg-server からping 10.0.8.2を実行しても応答がない。
終了状態
-
wg-client からping 10.0.8.1を実行すると応答が返ってくる。
-
wg-server からping 10.0.8.2を実行すると応答が返ってくる。
解説
クライアント側では公開鍵の不一致、エンドポイントのポート指定誤り、AllowedIPsによるCryptokey Routingの制限という3つの設定ミスが存在し、ハンドシェイクが成立しません。
サーバ側のOSには前の使用者が過去のコンテナ検証等で作成し、放置された仮想ブリッジインターフェース(VPNと重複するIP帯を主張している)が技術的負債として残置されており、ルーティングが競合している。
想定解法
clientのwireguardの設定を見にいくと、Peerセクションが色々間違っていることに気づく(PublicKey,Endpoint,AllowedIPs)
これを修正するため、先にserver側にログインして、publickeyを取得しておく
そして下記のように編集する
sudo su
cd /etc/wireguard/
vim wg0.conf
wg0.conf
[Interface]
PrivateKey = 0P9dze15vQgwsPm4VQ6blbloRdSdejhsROF3I9ELIWE=
Address = 10.0.8.2/24
[Peer]
PublicKey = bBl2BUud/HOxC7b1QoDyromN64Qme6lB4LssUwLwVgk=
Endpoint = 10.128.160.1:51820
AllowedIPs = 10.0.8.0/24
修正が完了したらサービスをリスタートする
sudo systemctl restart wg-quick@wg0
少し時間を置いてから、 wg showコマンドを打つ
root@1360-wg-client:/etc/wireguard# wg show
interface: wg0
public key: K4yDJfilzgEOcQosbegaLfK/fz2Hr6tUoYnXMzuZkws=
private key: (hidden)
listening port: 45966
peer: bBl2BUud/HOxC7b1QoDyromN64Qme6lB4LssUwLwVgk=
endpoint: 10.128.160.1:51820
allowed ips: 10.0.8.0/24
latest handshake: 1 minute, 20 seconds ago
transfer: 124 B received, 532 B sent
これによりハンドシェイクはできていることが確認できるが、この時点ではpingは通らない
sudo tcpdump -i wg0 -n icmp というコマンドをserver側で打ったあとPingを打つ
ping 10.0.8.1
こうすることによって、server側で
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on wg0, link-type RAW (Raw IP), snapshot length 262144 bytes
16:29:45.723797 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 1, length 64
16:29:46.771987 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 2, length 64
16:29:47.795783 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 3, length 64
16:29:48.820007 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 4, length 64
16:29:49.843653 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 5, length 64
16:29:50.869558 IP 10.0.8.2 > 10.0.8.1: ICMP echo request, id 1105, seq 6, length 64
^C
6 packets captured
6 packets received by filter
0 packets dropped by kernel
という結果が出来上がる
ここで、requestは届くが、応答がwg0から出ていないことが確認できます。
次に応答パケットがどこにあるかを確認するため、ip routeコマンドを使います
root@1360-wg-server:/home/ictsc# ip route
default via 192.168.60.254 dev eth0 proto static
10.0.8.0/25 dev br-40e13be8dda7 proto kernel scope link src 10.0.8.126 linkdown
10.0.8.0/24 dev wg0 proto kernel scope link src 10.0.8.1
10.128.160.0/30 dev eth1 proto kernel scope link src 10.128.160.1
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
192.168.60.0/24 dev eth0 proto kernel scope link src 192.168.60.1
この結果から、10.0.8.0/25 dev br-68da01e7461eと、dockerの存在が確認でき、Dockerが邪魔をしていることが確認できます。
次にこれを破壊するため、docker network lsで確認しに行きます
root@1360-wg-server:/home/ictsc# docker network ls
NETWORK ID NAME DRIVER SCOPE
e69108b61e33 bridge bridge local
0eb441368479 host host local
c97d361ce96d none null local
40e13be8dda7 old-k8s-test-net bridge local
そして最後、こいつを消します
root@1360-wg-server:/etc/wireguard# sudo docker network rm old-k8s-test-net
old-k8s-test-net
結果、pingが通るようになります。
root@1360-wg-server:/etc/wireguard# ping 10.0.8.2
PING 10.0.8.2 (10.0.8.2) 56(84) bytes of data.
64 bytes from 10.0.8.2: icmp_seq=1 ttl=64 time=1.39 ms
64 bytes from 10.0.8.2: icmp_seq=2 ttl=64 time=1.53 ms
root@1360-wg-client:/etc/wireguard# ping 10.0.8.1
PING 10.0.8.1 (10.0.8.1) 56(84) bytes of data.
64 bytes from 10.0.8.1: icmp_seq=1 ttl=64 time=4.66 ms
64 bytes from 10.0.8.1: icmp_seq=2 ttl=64 time=0.964 ms
ちなみにDocker自体を消してもOKだと思っています。
採点基準
-
PublicKey に wg-server の正しい公開鍵を指定している: 10%
-
Endpoint のポート番号を正しい値(51820)に修正している: 10%
-
AllowedIPs を自身のIPから、対向のネットワーク(10.0.8.0/24 等)に修正している: 10%
-
ルーティングを阻害しているDockerネットワークを特定し、無効化あるいは削除することでPingの応答を成立させている: 50%
-
再起動後もDockerネットワークが復活せず、終了状態(疎通可能な状態)が維持されている: 20%
注意点
-
Dockerネットワークが原因として確認できていない場合、50%の分を無効にしました。(原因が特定できていないのにできた、はダメだと個人的に思うため。)
-
制約違反の場合、点数は0としている。
講評
簡単な問題で、AIを使えば絶対に解ける問題でした。これからも発展していき、どんな問題も簡単に解決できるようになっていくのだと思います。
この問題のことと、私個人の意見として、原因を特定し、それがこれからも必要なのか、必要でないか、根本の意味を理解し、正しく取捨選択できるエンジニアになって欲しいと思います。