ICTSC2021 夏の陣にご参加いただいた学生の皆様、お疲れ様でした。
今回のICTSC2021 夏の陣は前回のICTSC2020の運営と新しいメンバー、それに加えて機材の提供や作問などでご助力いただいたスポンサー様方のおかげでなんとか開催し無事終了することができました 。参加していただいた方々につきましては、ここで培った知識・技術を今後に活かしていただければと思います。
今回出題した問題の問題文、及び問題解説を公開します。
ぜひ今後の研鑽にご利用いただければと思います。
ICTSC2021 夏の陣にご参加いただいた学生の皆様、お疲れ様でした。
今回のICTSC2021 夏の陣は前回のICTSC2020の運営と新しいメンバー、それに加えて機材の提供や作問などでご助力いただいたスポンサー様方のおかげでなんとか開催し無事終了することができました 。参加していただいた方々につきましては、ここで培った知識・技術を今後に活かしていただければと思います。
今回出題した問題の問題文、及び問題解説を公開します。
ぜひ今後の研鑽にご利用いただければと思います。
Go言語でWebアプリ開発を行っています。アプリのプロジェクトディレクトリは/home/user/test
にあり、このディレクトリでmake run
を実行することでアプリを起動することができます。
しかし、Ctrl+Cで終了させることができないため、他のターミナルからdocker stop
コマンドを叩いています。
大変なのでCtrl+Cで終了させたいです。どうすればできますか?
host
上に追加でパッケージをインストールしてはいけない。/home/user/test
にGo言語で書かれたWebアプリがある/home/user/test
をカレントディレクトリにし、make run
するとアプリを起動することができるdocker stop
で終了させることができるこの問題では、docker run
を実行する際に-it
オプションを指定していないためCtrl+Cで終了できなくなっていました。
-i, –interactive コンテナの STDIN にアタッチ
-t, –tty 疑似ターミナル (pseudo-TTY) を割り当て
https://docs.docker.jp/engine/reference/commandline/run.html
HostA から HostB への通信経路を冗長化しようとしているが、なぜかつながらない。原因を究明してつながるようにしてほしい。
HostA から HostB(192.168.19.129) に ping が通らない
デフォルトゲートウェイの冗長化をして、HostA から HostB(192.168.19.129) に ping が通るようにしてほしい
初期状態でRTA,SWB間は物理的に切れています。
HostAのstatic route を書き間違い
RTAにstatic route で流れているのでvrrp の仮想IPに設定しなおします
delete protocols static route 192.168.19.128/25 next-hop 192.168.19.2 set protocols static route 192.168.19.128/25 next-hop 192.168.19.126
VRRPで上流側のインターフェースのUP/DOWNを確認するヘルスチェックのスクリプトを書いたつもりが下流側のインターフェースをチェックしていたので下記のように書き換える
#!/bin/vbash source /opt/vyatta/etc/functions/script-template if ping -c 1 192.168.19.129 &> /dev/null then configure set high-availability vrrp group group1 priority '150' commit exit else configure set high-availability vrrp group group1 priority '50' commit exit fi
#!/bin/vbash source /opt/vyatta/etc/functions/script-template if ping -c 1 192.168.19.129 &> /dev/null then configure set high-availability vrrp group group1 priority '140' commit exit else configure set high-availability vrrp group group1 priority '40' commit exit fi
あなたはネットワーク開発事業部で働いています。ある日、コーヒーを飲んでいると、あなたの上司は次のようなことをいいました。
今、我が社では、新しい技術を使ってみようという取り組みがあって、Segment Routingっていうのをやってみることになったんだ。だけど、上手く通信ができなくて困っているんだ。君はスーパーエンジニアだって聞いているからこんな問題ちょちょいのちょいだよな!
あなたはスーパーエンジニアなので、この問題を解決してください。
これらの機器は顧客を模した機器です。
ログイン情報
補足
ログイン情報に記されたマシンにログインすると以下のようなプロンプトが表示されます。この画面で1, 2, 3, 4を選択することで所望の機器にログインすることができます。これらの機器は顧客を模した環境なので、設定を変更してはいけません。
これらの機器では、顧客ごとにVPNの設定が行われています。このうち、R1のみが設定変更が可能です。R1, R2はFRRを用いて経路を交換しています。
ルータの初期設定に必要なファイルは、/data/setup-interfaces.sh
に保存されており、setup-interfaces.service
を用いて設定しています。
ログイン情報
こんにちは。この問題を作問したえると(proelbtn)です。この問題は、LinuxのネットワークスタックやSegment Routingに関する問題です。
問題文にある通り、今回の問題では「R1, R2間でSegment Routingを使ってL3VPNを張りたいが、設定が上手く行ってないので疎通が取れない」という問題です。文章中のSegment Routingに触れる前に、普通のIPルーティングについて考えてみましょう。通常、ルータは、宛先IPアドレスのみを見てパケットを転送します。そのため、パケットがどこを中継して宛先に転送されるのかを、送信者が決定することはできません。
通常のルーティングに対し、送信者がパケットの経由地を指定することができるソースルーティングという転送方式があります。この方式では、送信者(もしくはパケットの転送者)が「そのパケットが通るべき経由地」をいくつか指定することができます。ソースルーティングには、パケットの経由地を全て指定するようなStrict Source Routingと、パケットの経由地をいくつか指定し、その間がどのように転送されるのかは問わないLoose Source Routingの二種類に分けることができます。そして、Segment Routingは後者のLoose Source Routingの一つです。
Segment Routingでは、Segmentと呼ばれるパケットに対する命令のリストをパケットにくっつけて転送することで、自由にパケットを操作することができるようになります。Segmentには様々な種類がありますが、よく使われるものについてはRFC8986で定義されています。例えば、次のようなものが定義されています。
パケットにSegmentのリストを格納する時に、何らかの形式にエンコードして格納する必要があります。MPLSのラベルとしてエンコードするような方式をSR-MPLSと、IPv6のアドレスとしてエンコードするような方式をSRv6と呼びます。SRv6の場合、Segmentの情報は以下のようにしてIPv6のアドレスにエンコードされます。
まずはじめに、router01に入り、VRF100のルーティングテーブルを見てみます。すると、172.31.2.0/24は、encap seg6 mode encap segs 1 [ 2001:db8:2::100 ] dev eth1 scope link
という処理をするように設定されています。
[email protected]:~$ ip route show vrf vrf100 172.31.1.0/24 dev eth2 proto kernel scope link src 172.31.1.254 172.31.2.0/24 encap seg6 mode encap segs 1 [ 2001:db8:2::100 ] dev eth1 scope link
この処理中の、encap seg6
というキーワードで検索をかけると、実際の設定がどのように行われるのか知ることができます。
先ほどのip route
の結果は、「2001:db8:2::100
というセグメントを、Segment Routing Headerに付与してパケットを転送しようとしている」という意味です。ですが、tcpdumpでパケットを確認してみても、パケットが転送されている様子は見られません。
[email protected]:~$ sudo tcpdump -ni eth2 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes 11:02:57.970658 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 6039, seq 47, length 64 11:02:58.994595 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 6039, seq 48, length 64 11:03:00.018665 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 6039, seq 49, length 64
[email protected]:~$ sudo tcpdump -ni eth1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes ^C 0 packets captured 0 packets received by filter 0 packets dropped by kernel
カーネルパラメータを確認すると、以下のように、net.ipv4.ip_forward
が0になっています。この状態では、転送されるパケットはdropされてしまいます。同様に、net.ipv6.conf.all.forwarding
も0になっています。
[email protected]:~$ sudo sysctl -a | grep net.ipv4.ip_forward net.ipv4.ip_forward = 0 net.ipv4.ip_forward_update_priority = 1 net.ipv4.ip_forward_use_pmtu = 0
そのため、vtyshでFRRに入り、以下のような設定を行います。
[email protected]:~$ sudo vtysh Hello, this is FRRouting (version 7.2.1). Copyright 1996-2005 Kunihiro Ishiguro, et al. router01# conf t router01(config)# ip forwarding router01(config)# ipv6 forwarding router01(config)#
この設定を入れると、パケットがSegment Routing Headerでカプセル化されて、eth1から送信されることが確認できます。ですが、この状態ではまだ、C21でパケットを受信しICMP Echo Replyが返るものの、C11でpingの応答を確認することはできません。同様に、C21からC11にpingを打つ場合でも、C11でパケットを受信することはできません。先ほどと同様にtcpdumpをすると、R1のeth1でパケットを受信できていないことが分かります。
R1のbgpdの様子を確認すると、R2から2001:db8:2::/64
の経路を受信しています。今回の構成では、LocatorはBGPで広報されていることが分かりますが、R1はR2に2001:db8:1::/64
を広報していません。この状態では、R2はパケットを転送することができません。そのため、R1のLocatorを広報するように設定します。
router01# show bgp ipv6 unicast BGP table version is 2, local router ID is 192.168.12.101, vrf id 0 Default local pref 100, local AS 65001 Status codes: s suppressed, d damped, h history, * valid, > best, = multipath, i internal, r RIB-failure, S Stale, R Removed Nexthop codes: @NNN nexthop's vrf id, < announce-nh-self Origin codes: i - IGP, e - EGP, ? - incomplete Network Next Hop Metric LocPrf Weight Path * 2001:db8::/64 fe80::9ea3:baff:fe2c:9be4 0 0 65002 ? *> :: 0 32768 ? *> 2001:db8:2::/64 fe80::9ea3:baff:fe2c:9be4 0 0 65002 i Displayed 2 routes and 3 total paths
[email protected]:~$ sudo vtysh Hello, this is FRRouting (version 7.2.1). Copyright 1996-2005 Kunihiro Ishiguro, et al. router01# router01# conf t router01(config)# router bgp 65001 router01(config-router)# address-family ipv6 unicast router01(config-router-af)# network 2001:db8:1::/64
すると、C11から打ったpingの応答がR1のeth1までやってくることが分かります。そして、setup-interfaces.shで設定されたEnd.DT4に従って、パケットがdecapsされ、VRF100に転送されます。しかし、eth2からパケットは送出されません。
[email protected]:~$ sudo tcpdump -ni eth1 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth1, link-type EN10MB (Ethernet), capture size 262144 bytes 08:24:54.616136 IP6 2001:db8::1 > 2001:db8:2::100: srcrt (len=2, type=4, segleft=0[|srcrt] 08:24:54.616606 IP6 2001:db8::2 > 2001:db8:1::100: srcrt (len=2, type=4, segleft=0[|srcrt] 08:24:55.640124 IP6 2001:db8::1 > 2001:db8:2::100: srcrt (len=2, type=4, segleft=0[|srcrt] 08:24:55.640715 IP6 2001:db8::2 > 2001:db8:1::100: srcrt (len=2, type=4, segleft=0[|srcrt] 08:24:56.664126 IP6 2001:db8::1 > 2001:db8:2::100: srcrt (len=2, type=4, segleft=0[|srcrt] 08:24:56.664688 IP6 2001:db8::2 > 2001:db8:1::100: srcrt (len=2, type=4, segleft=0[|srcrt] ^C 6 packets captured 6 packets received by filter 0 packets dropped by kernel [email protected]:~$ sudo tcpdump -ni vrf100 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on vrf100, link-type EN10MB (Ethernet), capture size 262144 bytes 08:26:13.464173 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2347, length 64 08:26:13.464922 IP 172.31.2.1 > 172.31.1.1: ICMP echo reply, id 827, seq 2347, length 64 08:26:14.488462 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2348, length 64 08:26:14.489234 IP 172.31.2.1 > 172.31.1.1: ICMP echo reply, id 827, seq 2348, length 64 08:26:15.512094 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2349, length 64 08:26:15.512605 IP 172.31.2.1 > 172.31.1.1: ICMP echo reply, id 827, seq 2349, length 64 ^C 6 packets captured 6 packets received by filter 0 packets dropped by kernel [email protected]:~$ sudo tcpdump -ni eth2 tcpdump: verbose output suppressed, use -v or -vv for full protocol decode listening on eth2, link-type EN10MB (Ethernet), capture size 262144 bytes 08:26:18.584126 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2352, length 64 08:26:19.608089 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2353, length 64 08:26:20.632100 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2354, length 64 08:26:21.656082 IP 172.31.1.1 > 172.31.2.1: ICMP echo request, id 827, seq 2355, length 64 ^C 4 packets captured 4 packets received by filter 0 packets dropped by kernel
これは、逆経路フィルターによってパケットが破棄されています。これは「あるパケットの応答は、受信したインターフェースから送られるか」どうかをチェックしています。End.DT4を実行した時点で、入ってきたインターフェースはVRFデバイスになっているものの、172.31.2.0/24の経路はeth1から送り出すというようになっています。このデバイスの不一致が原因でパケットが破棄されています。そのため、逆経路フィルターを無効化する必要があります。
[email protected]:~$ ip route show vrf vrf100 172.31.1.0/24 dev eth2 proto kernel scope link src 172.31.1.254 172.31.2.0/24 encap seg6 mode encap segs 1 [ 2001:db8:2::100 ] dev eth1 scope link
sudo sysctl net.ipv4.conf.all.rp_filter=0 sudo sysctl net.ipv4.conf.vrf100.rp_filter=0 sudo sysctl net.ipv4.conf.vrf200.rp_filter=0
すると、パケットが通ることが確認できます。
Linuxのネットワークスタックの設定のちょっとニッチな部分を突くような問題にしようと思っていたのですが、思いの他、Locatorの広報の部分で引っかかってしまっていて、解いてほしい部分じゃない部分に引っかかりを作ってしまったなとちょっと反省しています。ですが、最初想像していたよりは多くのチームが回答をしてくれていたのでとても嬉しかったです。
あなたはISPの従業員です。お客さんと契約し、お客さんの自宅にインターネット回線を提供します。
このISPはPPPoEではなくIPoE方式で接続します。
また通信はIPv6のみで行い、IPv4は使わないません。
IPv6アドレスはDHCPv6 Prefix delegationで降ってきます。
ところが、お客さんかISPのどちらかの設定ミスで、お客さんに正しくIPアドレスが割り振られないようです。
あなたはなんとかしてIPアドレスが割り振られるように直さないといけません。
2001:db8::/32
2001:db8:0070::/32
2001:db8:0070:2000::/52
2001:db8:0070:2100::/56
2001:db8:0070:2200::/56
2001:db8:0070:2n00::/56
fd9b:b0bc:3e87:e000::/52
clientのeth1に、ルーターがRA+SLAACしているアドレスが自動設定されない
clientのeth1に、ルーターがRA+SLAACしているアドレスが自動設定される
この問題は、DHCPv6 PD の問題に見せかけた RA 問題でした。
まず、ISP側のルーターには初期状態で以下のような設定が入っています。
set interfaces ethernet eth1 address 'fd9b:b0bc:3e87:e000::1/64' set service router-advert interface eth1 prefix 2001:db8:0070:2000::/52 // 以下略
これにより、eth1(クライアントとの接続NIC)に割り当てられたアドレスが管理用のULAなのに対して、RAでは2001:db8:0070:2000::/52
という奇妙なアドレスを広告しています。これによりRAが失敗しているので、解決方法としてはRAを修正します。
delete service router-advert interface eth1 set service router-advert interface eth1 prefix ::/64
アドレスを変更しても良い、という断りがあったため、ISP-クライアント間のネットワークで扱うアドレスをGUAに変更する場合も解答としてみなしました。
delete interfaces ethernet eth1 address 'fd9b:b0bc:3e87:e000::1/64' set interfaces ethernet eth1 address '2001:db8:0070:1000::1/64' set service router-advert interface eth1 prefix 2001:db8:0070:1000::/64
またこの場合、RAだけ変更してもeth1のアドレスを変更していない場合は、RA自体は飛びLLAでのルーティングはできますが、ルーターがGUAを使ってクライアントに疎通できない(GUAに対する経路が入らない)ため部分点としています。
DHCPv6 PDのサーバー側を触ったことがないと、つい移譲するアドレスと移譲に扱うネットワークのアドレスを混同しがちなので、二つのアドレスは異なるサブネットでも良い、と気づけるかがポイントでした。
DHCPv6 PDのクライアントやプロキシーは、自宅ラックをNTTのNGNなどに接続する際によく使いますが、サーバーとしての設定をしたことがある人はおそらく少ないと思います。
それにもかかわらず、粘り強く問題を解き見事正解の解答を導き出したチームが複数おり、作問者として大変嬉く思います。