MWC2024感想レポート

はじめに

こんにちは、BBSakura Networksの秋山です。
今回はスペインのバルセロナで開催されたMWC2024に来場者として参加させていただいたので、その感想をレポートしたいと思います。 MWCとは前回の記事で解説されているように総出展者数2700社以上、参加者は200カ国以上から10万人以上にも及ぶ大規模なモバイル通信関係の展示会です。
自分は普段OCXのバックエンド開発をしており、モバイル通信とは直接的な業務の関わりがない&まだ新卒2年目の若造だったということもあり、正直参加は難しいかなと思っていたのですが、立候補したら快く参加させてくれました。会社には感謝してもしきれません。

全体の所感としては、思ったよりモバイル通信に特化した展示というわけではなく、メインがAIやセキュリティでもモバイルが絡んでいればよしとしているような雰囲気があり、様々な製品を見ることができてとても楽しめました。もちろん、モバイル用のアンテナや監視ツールなど、モバイルに特化したものもあり、5日間ありましたが飽きることはなかったです。

MWC会場前にあったMWCと書かれたモニュメントの写真
MWC会場前にあったモニュメント

面白いと思った展示

6G対応アンテナ

Ericssonさんのブースで6G対応のアンテナが展示されていました。このアンテナはセンチメートル波を採用しており、7GHzから15GHzの周波数帯域を使うことができるように設計されているとのことです。8GHzという広い帯域での通信を実現するために、この四角のアンテナ内部で400MHzの帯域幅を持つアンテナ要素を組み合わせてアレイ(複数のアンテナ素子が連続して配置されている状態)を構成しているとのことで、そのアンテナ要素の制御に関する開発を進めているということでした。6Gが実際のモノとして実現されているのを見るのはこれが初めてで、5Gの先の6Gを既にここまで進めている企業もあるのかと衝撃を受けました。

Ericssonブース展示されていた6G対応の次世代型アンテナの画像
6G対応の次世代型アンテナ

量子通信

スペインの政府機関から補助を受けているグループが集まって量子通信に関する展示を出していました。モバイル通信とは直接的な関係はないですが、認証系で使われることが期待されるとのことでした。画像は量子通信で認証を行っている様子で、ラック内上部の機器が通信の暗号化におけるエンコードをしていて、ラック内下部の機器はその暗号化における鍵の発行を行っているそうです。量子通信は概念を聞いたことがあるくらいでしたが、実際に量子通信が実用化されているのを見るのは初めてで技術進歩の早さを実感しました。

2つのラックの上にそれぞれPCがあり、PCからラック、もう一方のラック、PCへ量子通信ができている様子
量子通信が行われている様子

モバイル銃痕分析機

スペインの警察も展示をしていました。展示されているのはモバイル銃痕分析機で画像の中で床に置いてある部分をリュックのように背負って、ケーブルの先を手に持って銃痕にあてがうようにして使うとのことです。手に持っている部分にはレーザー照射装置が内蔵されており、銃痕にレーザーを当てて、そのエネルギーで散った物質による光の波長変化をカメラで読み取って銃痕を分析するようです。想定されている銃痕として画像にある小さな拳銃の弾からアサルトライフルの弾まで想定されているようで、日本とは想定しているものが違うなと思ったのを覚えています。

モバイル銃痕分析機が展示されており、机の上のPCと繋がっている。机の上には薬莢がおいてあり、拳銃からライフルの薬莢がサンプルとして置いてある
モバイル銃痕分析機の展示

スペインでの生活

今回なぜ自分でもMWC2024に参加できたのかというと、旅程を組んでくださった方が旅費を徹底的に削って下さり、より多くの人間が参加できるようになったためです。飛行機はなるべく安い便で行き、宿もホテルではなくAirbnbで家を丸ごと借りて、参加メンバー全員で泊まっていました。家を借りているため、キッチンや調理器具が非常に充実しており、食事もほとんど参加メンバーで自炊していました。会社の人と一つ屋根の下で生活するというのはもちろん、同じ食卓を囲むという経験は新鮮で楽しかったです。
複数人が各々で食べたいものを作るとライスとピザとハンバーグの山が食卓に並ぶという知見を得ることができました。

各々が料理をした結果食卓に並んだのはライスとピザとハンバークの山
スペインでの自炊の様子

スペイン観光

空いた時間でスペインの観光もしました。遠出するほどの時間はなかったので、自分はバルセロナ市歴史博物館に行きました。ここはバルセロナの旧市街という場所の地下にあるという特徴があります。バルセロナの旧市街は地理的にはかつてのローマ時代に都市があった場所で、現在の旧市街はそのローマ時代の都市遺跡の上に建っている状況です。このバルセロナ市歴史博物館はその地下遺跡に繋がっており、地上は旧市街になってますが、地下に潜ると1000年以上前のローマ時代の遺跡に切り替わるので結構な衝撃がありました。

バルセロナ市歴史博物館の地下にローマ時代の民家などを含んだ街の遺跡がある
バルセロナ市歴史博物館の地下遺跡

最後に

今回のMWC2024での経験はとても貴重なものでした。6Gや量子通信など、今までニュースでしか接することがなかった技術を実際に目にし、スペインで生活や観光を経験することができて、参加の立候補をして本当に良かったと思います。こうした若手でも意欲があればチャンスを掴める環境をありがたく思うと共に、ここで得た経験をなるべく還元しながら来年以降も新たに若手が参加できる雰囲気作りに貢献したいと思います。

おまけ

スペインのゴミ出しは全種類毎日出せるらしく、便利さに感動しました

スペインの道路には大きなゴミ箱があり、毎日回収されている
スペインのゴミ出しはとても便利

MWC2024に参加してきました!

MWC2024とは?

MWCとはMobile World Congressといい、毎年2月末頃スペインのバルセロナで開催されている、世界最大のモバイル通信関係の展示会になります。 いわゆるMNO(Mobile Network Operator)国内だと、SoftBank、Docomo、KDDI、Rakutenだけではなく、Mobile Network向けのソリューションや周辺ビジネスを提供している企業さんも数多く出展されていて、その広さは日本最大の東京ビッグサイトの展示面積の2倍の20万㎡にも及びます。

総出展者数は、2700社以上、参加者は200カ国以上から10万人以上にも及び、コロナ禍で一時期参加者が落ち込る以前と比較しても多くなっています。

MWC2024の概要が記載されている画像、参加者10万人、出展者2700社以上、参加国205カ国
MWC2024

MWC2024全体の展示状況

MWCはその年によってIoTとか5Gとか大きなテーマがあり今回はAI一色になるかなと思っていたのですが、見本市ということもありそんなこともなかったです。 モバイル通信を含む周辺のビジネス全般を展示しているような企業が多く、例えばAIを使って障害のサポートをしてくれるとか、AIを使ってRU(無線ユニット)の設置場所や処理を行う基地局を適切に選定し続けてくれるというような、AIを活用した製品というようなものがちらほらとあるような感じで、あまり最新のという印象はうけませんでした。

中国企業の露出は相変わらずすごい!でも・・・

MWCに行かれたことのある方はご存知かもしれないですが、MWC会場は大きな8つのHallに分かれているのですが、その一つであるHall1の80%〜90%がHuawei社が占めています。1社で10,000㎡程度は占めていて、中国メーカーはいくつかの国では苦境に立たされているとされていますが会場ではまだまだ大きなプレゼンスはあった印象でした。 2018年のファーウェイさんのブースですが、どうでしょう?変わっていますか?変わってないですか?

MWC2024のHall1にあるファーウェイブースの写真、2018年と2024年の比較が出来るようにしている。
Hall1のブースの写真2018年‐2024年

ちなみに・・・

MWCというか、海外の展示会は出展されているそのものを見るというよりも、あらかじめアポイントを取った企業の意思決定権のある人や、次に繋げるためのミーティングがメインになっているという側面があります。そのため展示スペースの大部分がミーティングスペースだったり、そもそも展示しておらずミーティングスペースをメインにしている企業さんも多いです。会場のうちHall7の1/3程度がミーティングエリアになっているというと、どれくらいの企業がミーティングを重視しているかわかりますでしょうか?

MWC2024会場マップ、ミーティングエリアが塗りつぶされている。
MWC2024の会場

個人的に面白いなと思ったもの

会社としてはモバイルコア関係のものや、モバイル通信関係の企業をみてまわったので、そのあたりは他のかたがきっちり書くと思うので、ここでは個人的に面白かったものをいくつかご紹介します。

通常のサーバーを液浸する溶液と専用のケース

通常のサーバーを漬け込んで液冷にしてしまう機材 基本的にはどんなサーバー(メーカーが認めていなくても)も液冷に出来るという説明がされていました。 H100等を搭載したサーバーも稼働実績があるとのことなので、電力は潤沢にあるけど、新しく発熱量の多いサーバー機器を入れたい場合にはサーバールームやデータセンターの冷却機の更新が必要などというような状況であれば、利用もあるのかなと思いました。 ただ、データセンターの運用オペレーションが大きく変わってしまうので、なかなか難しくはありそうです。

サーバーが専用の液に浸かっている写真
液浸サーバー用溶液&ケース

IOWNに利用される(であろう)サーバー

富士通さんのブースに設置されていた、IOWNに利用されているサーバーとのことでした。 高性能で、消費電力に強みがあるとのことだったのですが、展示されている方的にはイチオシは写真の中央部に乗せてあるクーラーボックスだそう。 これは通常のクーラーボックスと入れ替えるだけで液冷にすることができるということを仰っていました。

サーバーの画像
サーバー機材

NECさんのブース

□ 動画送信をスムースにするための仕組み

NECさんのブースでは、モバイル通信を使った場合に必要なエリアのみのデータを送信することによって、動画全体がカクつくのを抑えるような仕組みや通信が遅くなるエリアでは接続先を切り替えて通信をすることによって、動画送信をスムースにする仕組みが展示されていました。 これは自動走行車(レベル3<異常時には人がリモート等で介在する>)などを利用する際に効果的で実用的なものであるなと思いました。

車両から撮影した動画をデータ転送した際の画像貼り付けられている、NECの技術を利用しない場合は動画全体がカクついているのに対し、利用した場合には動画が鮮明になっている。
NECが開発した技術を使う場合使わない場合

□ NECの生成AI

NECの生成AIは動画を読み込ませるとどのような状況であったのかを日本語の説明文を作成出来るというものでした。 実際の動画でも交通事故の動画を読み込ませて、何が起こったかを生成していました。読み込まれた動画はオートバイと自動車の接触事故で生成された文章は、自動車がオートバイの動きをよく確認しなかったため事故が発生したと思われるというようなものでした。 しかし、私が感じたのはオートバイが車線変更を実施した際に、車の確認をしていないために発生したのではないかと感じたので、かなりの乖離があり、利用方法としては、事故発生時の動画を読み込ませて事故の当事者が納得したのなら、そのまま保険等の負担割合を決めて、納得できなければこれまでどおり保険調査員が介在するような形で省力化を計っていくというような使い方でできそうでした。

いずれも実用が近そうで面白かったです。

NECの生成AIの説明画像
NECの生成AIの説明画像

日本ブース!

海外の展示会には各国が国として展示をして、各国のソリューションのアピールをしているものがあります。 日本もMWCの展示で力を入れており、Hall6総務省がすでに製品化されているようなものを持っている企業と、4YFNでJETEROがスタートアップでこれからソリューションが出来るような企業とそれぞれ展示しておられました。

日本ブースの写真
日本ブース
4YFNは4年後に来る(かもしれない)という技術の展示なので荒削りですが、非常に面白いものがたくさんあります!

JETROブースの写真
JETROブース

BBSの継続的な海外展示会参加に向けて

個人的には、特定の人だけが行き続けるというよりはなるべく多くのワカモノに行ってほしいという希望があります。

MWC開催タイミングのホテルや飛行機はめちゃ高です。 普通のホテルでも1泊5万円とかザラで、飛行機も高くなる傾向があります。

なので、普通のやり方ではコスト的に多くのワカモノには行ってもらえないので、下記のようにやっていくのはどうかな?

当たり前ですが、楽しいから行くというような理由は企業では通用しません、きちんと目的とどのような成果が得られるかの説明ができる状態にしておくことは必要です。

そのうえで

 行くこと自体はとにかく早く決めておく

 決めることによって、ホテルその他の予約が非常に安価にできます。宿泊場所も都合の良いところが安く、キャンセルポリシーも有利な場合が多いです。  航空券も早めに抑えることによって、相当コストが抑えられます。たくさんのワカモノに行ってもらおうとすると、こういうのって重要です。

 ちなみに、今回当社の若者たちは、MWC会場から地下鉄で1本、ドア2ドアで20分くらいのところに、Airbnbで一軒家を丸ごと借りて、6日間ほど過ごしていました。最大9名まで泊まれて、6日間で60万円ちょっとなので、なかなかリーズナブルであったのかなと思います。

リビングルームの画像
Airbnbで宿泊した施設

 こういうイベントごとは、決まった人が常に行くというよりは、新しいことに敏感で挑戦をしようとするワカモノにこそ多く行ってほしいと思っていてできれば次のワカモノに同じように紡いで行ってほしいなと思います。

最後に

実は、バルセロナの最終日に会食に行った先でスリにあいました。 スリが多いのは以前行ったときから認識していたのですが、以前よりも会場の治安が良くなっていた気がしており、気が緩んでいたのかもしれないですね。

本当に体の正面に掛けていた、ボディーバックから引っこ抜いていったと推測しています。 正面からチラシのようなものを持って近づいてきて、眼の前でゆらゆらさせて気を引き、その隙に引っこ抜かれた(と思う)のですが、その時には全く気が付きませんでした。

幸い盗られたのはiPhoneだけで、保険が利用できて金銭的な被害は最少で済んだのですがみなさんも行かれるときには気をつけて下さい。

ボディーバックからiPhoneをスられている画像、生成AIで作成されている。
iPhoneをスられた

ちなみに、盗られたiPhoneを「探す」でしばらく見ていたのですが、バルセロナ市内をウロウロした後、バルセロナから車で1時間程度の場所に行って消息を絶ちました、たぶんバラされて売られていったのでしょう。

さて、こんな感じでMWC参加してきましたが、もちろん当社もしっかりと他社さんと面談しモバイルやOCX方面のビジネス面でもいろいろ進めさせていただいております。当社にご興味がありましたら、ぜひカジュアル面談しましょう! www.bbsakura.net

バルセロナの地図、盗られたiPhoneが移動している状態が示されている。
盗られたiPhoneの動き

おまけ。MWCで見た、(本当に)変わったもの

 ひとのみみ型マイクがついたマネキン

 これは、スマホが人の耳にどのように聞こえているのかを測定する計測器です。  ものすごくニッチですが、こういうものもありました。

マネキンの画像
マネキンの画像

 脳卒中かどうかを調べるための装置

 展示していた企業によると脳卒中なのに病院に連れて行くなど適切な処置をしないことによって、死亡する例があるらしく、このヘッドギアをつけて計測すれば病院に行かなくてはならないかどうかがわかるというものだそうで、医療へのアクセスのしやすさが異なる国ではこういった需要もあるのかもしれませんね。

ヘッドギアをつけたマネキンの首部分の画像
ヘッドギアをつけたマネキンの首部分

新卒のJANOG53体験記

はじめに

こんにちは、BBSakura Networks株式会社(以降BBSakura)にてOCXのクラウド直接接続まわりを担当してる太田です。

今回は新卒の私が初めてJANOGに現地参加した際の面白かったテーマについて2つ記述してみようかなと思います。

NETCON

www.janog.gr.jp

NETCONとは

上記サイトの文言だとNETCONとは

ネットワークエンジニアのためのコンテストです。JANOG参加者が誰でも参加できるネットワークコンテストを開催します。コンテストでは、実際にトラブルが起きているネットワーク環境を提供します。 それらを実際に解いていただくことで、ネットワークエンジニアとしてトラブルシューティングの勘を高めていこうという企画です。

だそうです。ここで私が引っかかったのが2点。

  1. ネットワークエンジニアのための →まだネットワークエンジニアを名乗るには早すぎる私が参加して大丈夫なのか

  2. JANOG参加者が誰でも参加できる →え、もはやネットワークエンジニアじゃなくても参加できる?

と難易度が全く分からず、参加して大丈夫なのか不安でしたが、「現地問題」という現地でしか解けない問題があったので部屋に寄ってみることにしました。

現地問題

(写真を撮り忘れたのが恐縮ですが)現地問題ではスイッチ、ルーター、光ケーブルなどなど実際の物を用いたトラブルシューティングを行うのが、オンライン問題との大きな違いです。(ちなみに現地問題は合計で4問でしたがオンライン問題は約30問ありました)

私が取り組んだ問題がこちらです。(答えも載っています) note.com

要約すると

  • 機器にSFPも光ケーブルも刺してるのにリンクアップしない。どうにかしてリンクアップさせてください。

という内容です。

私は物理機器を全く触ったことがなかったので、右も左も分からず、とりあえず何をすればいいかをスタッフの方に聞きました。 すると「まずはハードウェアのインターフェースの情報が見れるコマンド」を探してみようと言われたので、ひたすらググり続け、見つけたコマンドを打っては「いや、これ違うな」を繰り返していました。(そもそもベンダーによってコマンド違うのなんとかしてくれ)

そして最終的に見つけたコマンドが

show chassis hardware

です。これをJuniper機器で打つとハードウェアに関する様々な情報が出てきますが、その中にインタフェースに刺さってるSFPモジュールの情報が出てきます。

今回は最初に両ポートに刺さってたSFPモジュールが一致していなかったため、片方を抜いてもう片方に合わせてあげるとリンクアップするという内容でした。

とまあここでは簡単に書きましたが、実際は何も分からない中、ほぼ全てスタッフさんに導いて頂き、なんとか回答に辿り着いています。ありがとうございました。

結果的に誰でも参加できるは正しかったですね(次はもう少し自力で解けるようになりたい)

エンジニアのキャリアパス古今東西 ~エンジニアが経営に参加してみたら見えるようになった世界~

www.janog.gr.jp

JANOGでは、登壇者が大勢の聴衆に向かって特定のテーマを元に語りかけ、聴衆の質問を受けながら議論を深めていくミーティング形式のプログラムが複数開催されています。プログラムの中には難しい技術的な要素を含むものも多いですが、誰にとっても聞きやすい系のものもあります。

今回私が取り上げるのはその中の一つで、エンジニアのキャリアパスについて語られていたものです。登壇者は4名でそれぞれが

  • エンジニアをやっていたら, ~~~~~になっていました

といった方々です。この中で1人次元が違うなあと感じた方がいるのでその方について思ったことを書いていこうと思います

その方のスペックは

  • 34歳時点でCOO
  • 学生時代にCCNPを取得
  • 転職3回

と言った感じで正直凄すぎて参考にならないと感じましたが、その方が仰っていたことの中で以下のような点は実践することができるのではないかと思いました。

  • 予算・納期のことは常に考える
  • 20代のうちはいいマネージャーを探し徹底的に観察
  • CCNPを取得(大変そう)

他にもマインドのことや管理職になって変わったことなど色々仰られていましたが、果たして自分はエンジニアに向いているのか、管理職・経営に向いているのかも考えさせられるプログラムでした。20代もあっという間に終わる気がしているので日々を大切に過ごしたいです。

おわりに

初めてのJANOGでしたが、多くの刺激をもらったと同時に「いつになったらこの方々のレベルに到達できるんだろうか」と虚無感にも駆られました。まずは「ネットワークエンジニア」を名乗れる段階まで成長し、いつかはJANOGで発表する側、そしてこんな記事を書かれる側に回れる日が来るように、日々精進していきます。

OCXを支える技術 #4 Building the OCX Identity Provider System with Kratos and Hydra / Kratos と Hydra で作る認証認可基盤

Japanese follows English.

和訳は英語の次に記載されています。

Hello, I'm Atreya, a full-stack engineer at BBSakura Networks where I lead the UI team and oversee our identity provider's development and maintenance. I also collaborate closely with our API team, lending a hand in backend tasks if required, since I was involved in backend development as well during the early phases of the project.

Identity management has always been an integral component of modern applications and for software engineers seeking to construct a bespoke identity provider system, understanding the underlying architecture is essential. In this article, I'll be sharing insights into how I built our in-house identity provider system using open-source solutions: Kratos and Hydra.

What is an Identity Provider?

At the core of any robust digital solution is an identity provider (IdP) system. An IdP system is essentially the backbone that supports user authentication (verifying who the user is) and authorization (determining what the user can do).

The Core Components of our IdP System

Our IdP system comprises the following critical components:

  1. OCX Identity Provider: This server is at the heart of our system. Not only does it render the UI, but it also operates as a bridge between Hydra and Kratos. With Kratos already offering a configuration option to integrate Hydra, our Golang server focuses on rendering the UI, handling consent and logout requests, and forwarding the generated access token to our frontend console.

  2. Hydra: An open-source OIDC-compliant OAuth2 Server, Hydra's primary responsibility in our setup is to issue access tokens once the user is authenticated through Kratos. This ensures that our backend only needs to validate the access token for each API request.

  3. Kratos: A headless, open-source identity management system, Kratos provides the authentication mechanics. By being headless, it offers the flexibility to design a UI consistent with our system's overall design and functionality.

The following diagram illustrates how the three components talk to each other:

a sequence diagram illustrating how the three components talk each other. From left to right, the four participants are placed: OAuth 2 Client (Browser), OCX Identity Provider, ORY Hydra, and ORY Kratos. The sequence is as follows:  1. the OAuth 2 Client initiates an authorization code flow or an implicit flow request to Hydra. 2. Hydra verifies that there is no user session, i.e. the end user is not authenticated. 3. Hydra redirects to the OCX Identity Provider and sends a request with login challenge. 4. If there is no valid flow ID, the OCX Identity Provider retrieves the authentication details. 5. If there is no user session, the OCX Identity Provider follows link to '/self-service/login/browser?return_to="/login?refresh=true&login_challenge=xxx"'. 6. Kratos creates and stores a new login flow. 7. Kratos returns 'HTTP 302 Found <selfservice.flows.login.ui_url>?flow=<flow-id>' to the OCX Identity Provider. 8. OCX Identity Provider shows the login UI to the client (browser). 9. The user fills out the form and clicks login. 10. OCX Identity Provider submits the form to Kratos with 'POST /self-service/login/browser?flow=<flow-id>'. 11. Kratos validates the form and sets a cookie on the client (browser). 12. OCX Identity Provider redirects to Hydra's redirect URL with the verifier.  13. Hydra redirects to the consent endpoint '/oauth2/auth/requests/consent' with the concent challenge. 14. OCX Identity Provider obtains and accepts detailed information about the requested scope (OpenID, OCX Portal, etc.) 15. OCX Identity Provider redirects to the Hydra redirect URL with the verifier. 16. Hydra verifies grant. 17. Hydra sends an access token to the client (browser).

Why Kratos and Hydra?

Developing an identity provider from scratch is a daunting task. Instead of reinventing the wheel, we decided to stand on the shoulders of giants: Kratos and Hydra. Our choice was strategic. Both tools are open-source and built using Golang, a language we're familiar and comfortable with. This not only ensures a smooth integration with our backend service, but also makes it feasible for our team to contribute back, be it bug fixes or feature enhancements. I've personally fixed a bug (https://github.com/ory/kratos/pull/2507) and proposed a new feature (https://github.com/ory/kratos/issues/3037) to Kratos which I am currently developing.

On the frontend, we are using Next.js along with NextAuth.js. NextAuth.js simplifies the task of setting up custom OIDC-compliant OAuth2 servers with Next.js. All that needs to be done is register an OAuth client ID and client secret in Hydra and setting up the client ID and secret from Hydra into the NextAuth configuration. The result is a seamless bridge between our frontend console with our identity provider system.

It's worth noting that while Kratos is our choice for storing fundamental authentication details, the majority of business-centric data, including user roles, preferences, and more, is safely housed in our backend database. This clear demarcation ensures system clarity and efficiency.

Why not use services like Auth0 or Okta?

You might wonder, why not adopt mainstream services like Auth0 or Okta? Here's why:

  1. Control Over User Data: With our chosen setup, we have complete control over user data.

  2. Transparency: As Kratos is open-source, we're privy to how the data is saved. This transparency is paramount from a security perspective. Being open-source, Kratos affords us a detailed look into its workings. To illustrate, here's the schema of the tables that store user data.

an ER diagram illustrating the schema of the tables that store user data. There are seven tables (networks, identities, identity_credential_types, identity_credentials, identity_verifiable_addresses, identity_recovery_addresses, identity_credential_identifiers ), with columns and relationships for each table.

Final Thoughts

Incorporating existing, robust solutions like Kratos and Hydra allowed us to focus on optimizing our business logic rather than grappling with the foundational challenges of developing an identity provider from scratch. The synergy between these tools and our custom Golang server resulted in an IdP system that is not only efficient but also scalable and maintainable.

For those interested in diving deeper, Kratos and Hydra both boast excellent documentation ( https://www.ory.sh/docs/ecosystem/projects ) . While we chose the self-hosted open-source versions of Kratos and Hydra, it's worth noting that Ory, the company steering the development of these tools, offers a managed cloud service. This might appeal to those who prefer a managed service over the responsibility of hosting by themselves.

Additionally, an open-source example of Kratos-Hydra integration using Golang can be explored here ( https://github.com/atreya2011/go-kratos-test/tree/hydra-consent ). Building on top of proven platforms accelerates development and ensures that we're working with industry-tested security and performance standards. In essence, it's about smart engineering.

Happy coding!

Disclaimer: This article is not an endorsement of Kratos and Hydra.

日本語訳

こんにちは、BBSakura Networksのフルスタックエンジニア、アトレヤです。UIチームをリードしており、認証認可基盤の開発とメンテナンスも行っています。また、プロジェクトの初期段階ではバックエンド開発にも携わっていたため、必要に応じてAPIチームと密接に協力し、バックエンドのタスクにも手を貸しています。

「アイデンティティ管理」はモダンなアプリケーションに不可欠な要素であり、専用の認証認可基盤を構築しようとするソフトウェアエンジニアにとって、基盤となるアーキテクチャを理解することは極めて重要です。この記事では、オープンソースのソリューション、Kratos と Hydra を使用して認証認可基盤を構築した方法についての知見を共有します。

Identity Provider とは何か?

全ての堅牢なデジタル・ソリューションのコアには、認証認可基盤があります。認証認可基盤は基本的に、ユーザー認証(ユーザーが誰であるかを確認すること)と認可(ユーザーが何をできるかを決定すること)をサポートするバックボーンです。

OCXの認証認可基盤のコアコンポーネント

OCXの認証認可基盤は、以下の重要なコンポーネントで構成されています。

  1. OCX Identity Provider: このサーバーはOCXのシステムの中心にあります。UIをレンダリングするだけでなく、HydraとKratos間のブリッジとしても動作します。Kratosは元々Hydraを統合する設定オプションを提供しており、"OCX Identity Provider" はUIのレンダリング、コンセントとログアウト・リクエストの処理、生成されたアクセストークンをフロントエンドに転送することにフォーカスしています。
  2. Hydra: OIDC準拠のオープンソースOAuth2サーバであるHydraの主な役割は、ユーザがKratosを通して認証された後にアクセストークンを発行することです。これにより、OCXのバックエンドはAPIリクエスト毎にアクセストークンを検証するだけでよくなります。
  3. Kratos: オープンソースのヘッドレスなアイデンティティ管理システムであるKratosは認証の仕組みを提供します。ヘッドレスであることで、OCXのシステム全体のデザインと機能性に合致したUIを設計する柔軟性を提供します。

実際の処理の流れは、以下のシーケンス図を参考にしてください。

コアコンポーネント間のやりとりを示すシーケンス図。左から、OAuth 2 Client (Browser), OCX Identity Provider, ORY Hydra, ORY Kratos の 4 つの登場人物が配置されています。シーケンスは以下の通りです。1. OAuth 2 Client は Hydra に対して 認可コードフローまたはインプリシットフローのリクエストを開始します。2. Hydra はユーザーセッションがない、つまりエンドユーザーが認証されていないことを確認します。3. Hydra は OCX Identity Provider にリダイレクトし、認証のためのチャレンジを含むリクエストを送信します。4. 有効なフロー ID がない場合、OCX Identity Provider は認証情報の詳細を取得します。5. ユーザセッションがない場合、OCX Identity Provider は Kratos に対して '/self-service/login/browser?return_to="/login?refresh=true&login_challenge=xxx"' のリンクを辿ります。6. Kratos は新しいログインフローを作成および保存します。7. Kratos から OCX Identity Provider に 'HTTP 302 Found <selfservice.flows.login.ui_url>?flow=<flow-id>' を返します。8. OCX Identity Provider はクライアント(ブラウザ)にログイン UI を表示させます。9. ユーザーがフォームを埋めてログインをクリックします。10. OCX Identity Provider は Kratos に対して 'POST /self-service/login/browser?flow=<flow-id>' でフォーム送信します。11. Kratos はフォームの有効性を検証し、クライアント(ブラウザ)に cookie を設定します。12. OCX Identity Provider はベリファイアとともに Hydra のリダイレクト URL にリダイレクトします。13. Hydra はチャレンジとともに同意エンドポイント '/oauth2/auth/requests/consent' にリダイレクトします。14. OCX Identity Provider は要求されているスコープ(OpenID, OCX ポータルなど)について詳細な情報を取得し、受け入れます。15. OCX Identity Provider はベリファイアとともに Hydra のリダイレクト URL にリダイレクトします。16. Hydra は権限を確認します。17. Hydra はクライアント(ブラウザ)に対してアクセストークンを送信します。

なぜKratosとHydraなのか?

認証認可基盤をゼロから開発するのは大変な作業です。車輪を再発明するのではなく、我々開発陣は巨人(HydraとKratos)の肩の上に立つことに決めました。この選択は戦略的でした。KratosもHydraもオープンソースで、開発陣が慣れ親しんでいるGolang言語を使って開発されています。これは、OCXのバックエンドとのスムーズな統合を保証するだけでなく、バグ修正や機能拡張などにOCXのチームメンバーが貢献することを可能にします。私自身、バグ ( https://github.com/ory/kratos/pull/2507 ) を修正し、現在開発中の新機能 ( https://github.com/ory/kratos/issues/3037 ) をKratosをメンテしているOry社に提案しました。

フロントエンドでは、Next.jsとNextAuth.jsを使用しています。NextAuth.jsでNext.jsにカスタムのOIDC準拠のOAuth2サーバをセットアップする作業が簡単になります。HydraにOAuthのクライアントIDとシークレットを登録し、NextAuth.jsのコンフイグにこのクライアントIDとシークレットを設定するだけです。その結果、OCXフロントエンドのコンソールと認証認可基盤をシームレスにつなぐことが可能になります。

Kratosは基本的な認証情報を保存するために使用されており、ユーザのロールなどを含むビジネス中心のデータの大部分は、違うバックエンドデータベースに安全に格納されています。この明確な区分により、システムの明瞭性と効率性が保証されます。

なぜAuth0やOktaのようなサービスを使わないのか?

Auth0やOktaのような主流のサービスを採用していない理由は以下の通りとなります。

  1. ユーザデータの管理: ユーザデータを独自に管理することができます。

  2. 透明性: Kratosはオープンソースであるため、データがどのように保存されるかを知ることができます。この透明性はセキュリティの観点から最も重要なことです。オープンソースであるため、その仕組みを見ることもできます。例として、ユーザデータを格納するテーブルのスキーマは以下の通りとなります。

ユーザデータを格納するテーブルのスキーマを表す ER 図。7 つのテーブル(networks, identities, identity_credential_types, identity_credentials, identity_verifiable_addresses, identity_recovery_addresses, identity_credential_identifiers )があり、各テーブルのカラムや関係性が書かれています。

最後に

KratosやHydraのような既存の堅牢なソリューションを組み込むことで、認証認可基盤をゼロから開発する基礎的な課題に取り組むよりも、ビジネスロジックの最適化に集中することができました。これらのツールとカスタムGolangサーバであるOCX Identity Providerとの相乗効果により、効率的であるだけでなく、スケーラブルでメンテナブルな認証認可基盤を構築することができました。

KratosとHydraはどちらも優れたドキュメントがあるのでぜひ読んでみてください ( https://www.ory.sh/docs/ecosystem/projects ) 。OCXではKratosとHydraのセルフホスト型のオープンソース版を選びましたが、これらのツールの開発を主導しているOry社がマネージドクラウドサービスも提供しています。これは、自分でホスティングして責任を負うよりも、マネージドサービスが良いというチームには合っていると思います。

さらに、Golangを使用したKratosとHydraのブリッジ実装のオープンソース例をこのレポ ( https://github.com/atreya2011/go-kratos-test/tree/hydra-consent ) で見ることができます。実績のあるプラットフォームの上に認証認可基盤を構築することで、開発を加速し、業界でテストされたセキュリティとパフォーマンスの標準を確実に使用することができます。要するに、スマートエンジニアリングということです。

ハッピー・コーディング!

www.DeepL.com/Translator (無料版)で翻訳し、修正したものです。

海底ケーブル巡りをしてきました!(南大東島編)

はじめに

この記事は BBSakura Networks Advent Calendar 2023 の 24 日目の記事です。

adventar.org

こんにちは、BBSakura NetworksのOCX開発チームに所属している秋葉です。
普段はOCXのバックエンド側の実装をメインに行っています。
趣味でインフラ設備巡りをすることがあるのですが、先日南大東島に海底ケーブルを見に行く機会がありましたので、写真と共にその様子をお届けします!

本編の前に...

そもそも海底ケーブルがどこに引かれているのかですが、当てもなく片っ端から海沿いを歩いて探すわけにはいきません。(それはそれで楽しそうではありますが...)
海洋状況表示システム(海しる)という便利なサイトがあり、こちらにざっくりと海底ケーブルのルートがまとめられています。

海しるで見た沖縄本島周辺の海底ケーブルMAP。
海しるで見た沖縄本島周辺の海底ケーブルMAP
画像のピンク色の線が海底ケーブルです。沖縄の周りだけでも結構ありますね...!
この地図とgoogle mapを見比べて、地形などからおおよその場所を絞って現地に行きます。

本編スタート!

南大東空港の滑走路と駐機中の旅客機。
南大東空港
(南大東空港で記念に1枚パシャリ)

その1

海しるで見た南大東島周辺の海底ケーブル。島の南西に1本海底ケーブルが引かれている。
海しるで見た南大東島周辺の海底ケーブル
海しるで見てみると、島の南西に1本海底ケーブルが引いてあるようです。
早速行ってみましょう。

NTT西日本南大東無線中継局と林の中に設置された2台の巨大なパラボラアンテナ。
NTT西日本南大東無線中継局のパラボラアンテナ
立派なアンテナが!NTTの無線中継局のようです。
ここからさらに奥へ進むと、海底ケーブルが来ているあたりまで行けそうなので、先に進んでみます。

軽自動車がぎりぎり通れそうなくらいの未舗装路が続いている。道の両端には雑草が生い茂っている。
目当ての海底ケーブルまでの道のり1
おや...

未舗装路が途切れ、ごつごつした岩と生い茂る植物の上に木板で作られた人ひとりが通れそうな道が続いている。
目当ての海底ケーブルまでの道のり2
だんだん道が険しく.....

木板で作られた道も途中で無くなり、気を抜けば足を取られそうなほど足場の険しい岩場が海まで続いている。
目当ての海底ケーブルまでの道のり3
ぎりぎりまで海に近づいたのですが、足場が悪くこれ以上は進まない方が良さそうなためここで断念です><
まわりに陸標やそれっぽい目印などがないか探してみたのですが、見当たらず、、
島に来ている唯一の海底ケーブルのため見てみたかったのですが、、残念!

その2...?

海底ケーブル敷設工事中の看板
海底ケーブル敷設工事中の看板
先ほどの海底ケーブルを探している途中、珍しいものを見つけました。

木々の間を抜けて海の方向に伸びている新設予定のケーブルルートを示すワイヤー。
新設するケーブルのルート1
新設するケーブルのルートのようです!!
ちょうど島を訪れたタイミングが工事期間と被っていたようで、なかなか貴重なものが見れました。

険しい岩場の間を抜けて、海の手前で岩に固定されている新設予定のケーブルルートを示すワイヤー。
新設するケーブルのルート2
こちらはしっかりと海まで!!
(ボカシを入れているのは一緒に見に行った会社の方々です。インフラ設備の写真撮ってる集団って、はたから見ると怪しい人たちに見えますね、、

最後に

既設の海底ケーブルや陸標を見つけることはできませんでしたが、かわりになかなかレアなものが見られたので大変満足です。また来年あたりに様子を見に行ってみようと思います!
以上、海底ケーブル巡り(南大東島編)でした!!

最後に南大東島で見つけたインフラ設備の写真を何枚か♪

木の葉が茂る手前に「南大東村」と書かれたパラボラアンテナが 2 つ並んでいる
「南大東村」と書かれたパラボラアンテナ
南大東対空通信局舎と、聳え立つ2本のアンテナ
南大東対空通信局舎
KDDIの携帯基地局と併設されている小型のパラボラアンテナ
KDDIの携帯基地局
聳え立つNTT西日本南大東大池無線中継所の巨大な鉄塔
NTT西日本南大東大池無線中継所
鉄塔に設置されたパラボラアンテナと、命綱をつけた作業員
NTT西日本南大東大池無線中継所

MPTCPのスケジューラーをeBPFで書けるようになった話

この記事は BBSakura Networks Advent Calendar 2023 の 25 日目の記事です。

こんにちは。BBSakura でソフトウェアエンジニアをしています早坂(@takemioIO|@gtpv2) と申します。

普段はモバイル開発グループという組織でモバイルコアの開発・運用をしていますが、その傍ら技術広報活動もしています。

技術広報に関しては 1日目の記事 で弊社のみずきさん(@n0mzk|@n0mzk.bsky.social)が書いていますのでぜひご覧ください。

そして自分はこのアドベントカレンダーの主宰もやっております。

今年で(学生時代のアルバイトから数えて)3 回目の主宰ですが、なんと今回は誰かが記事を無理やり 2,3 本書かずとも無事達成しました。

いやー人が集まらず毎年 2 本は書いていたので嬉しいですね。3 年目にしてやっと達成です。なので今年は頑張ったし 25 日の大トリをもらってもよいだろうということで最終日をもらうこととしました。来年も 25 日を取りたいですね。そして 1 本の記事にちゃんと労力を掛けられることって最高なんだなと思いましたね。

無事最終日を迎えられてホッとしております。


さて、雑談は程々にしておくとして、この記事は最近の MPTCP に関してのあれこれと、マルチパス技術の肝であるスケジューラーを eBPF で書けるようになったんだぜ?みたいな話をする記事です。しばらくお付き合いください。

MPTCPとは

MPTCP(Multipath TCP) とは TCP のマルチパス化技術のことです。MPTCP は任意のインターフェースに紐づく複数の TCP コネクション(以降 subflow と呼ぶ)をバンドルして、通信の帯域を拡張したり、適切なパスを使ったりすることで、通信を最適化する技術です。例えば任意のパスの通信品質が悪くなった時に流す流量を減らして制御したり・違うパスにフォールバックするなど Active Active, Active Standby なパスの使い方が可能です。

MPTCP という技術はちょうど 10 年前(2013 年)に RFC6824 MPTCPv0 として RFC 化されました。現在では RFC8684 MPTCPv1 と呼ばれるものが現行の最新です。Linuxカーネルのサポート も 5.6 から v1 のサポートに切り替わりました。

MPTCPスケジューラーとは

MPTCPスケジューラーとは、利用している subflow に対してどれくらいパケットを投げるかを決定するために使われます。

例えば A の subflow(A の Interface を持つパスと言い換えても良い)の調子が悪くなったので B の subflow に流量を増やしたりするのはこのスケジューラーのアルゴリズムで決定されます。

このスケジューラーには BLEST1というアルゴリズムをベースにしたのが現在の Linux のデフォルトで使われていたり、他にも Round-Robin や Lowest-RTT-First2など利用するアプリケーションの最適化戦略によって様々なアルゴリズムに変更可能なことが知られています。

最近の MPTCP を取り巻く環境の話

前述した通り MPTCP 自体は RFC 化から約 10 年の歴史があるのですが、現在ではどれくらい使われているのでしょうか。

Multipath TCP Measurement Service3という論文を眺めてみると、数年で 20 倍に増加したという話が書かれています。

この論文を書いた人たちは ZMap を利用して IPv4 の空間全体と IPv6 Hitlist4を使って IPv6 の一部を現在も計測していて、その計測データを mptcp.io というサイトで可視化しています。

IPv4 を見ると現在では MPTCPv0 を 80 番 ポートで動かしているのは 400k Addresses を超える程に達しました。

IPv4 での MPTCP 利用数のグラフ。徐々に増えており現在では 400k Addresses を超えていることが示されている
IPv4でのMPTCP利用数

MPTCP を取り扱うための整備も進み、Linux では MPTCPv1 を前提にした mptcpd というデーモンも実装されています。

これを利用することで path management を行うことができます。更に付随している mptcpize コマンドラインツールを使うと TCP を利用したアプリケーションを書き換えやリビルド等の変更を実施せずに MPTCP を活用できます。 実際に TCP に対応した iperf3 で使うと以下のようになります。

mptcpize run iperf3 -s

これは 、LD_PRELOAD 環境変数を使い glibc をオーバーライドすることで実現しています。そのためアプリケーションの更新は不要になります。Go 言語では glibc に依存させずにビルドが可能です。このケースでは当然ですが環境に依存しない故に動かすことができません。

最近では Go言語v1.21のパッケージの中でMPTCPサポート が入るようになりました。以下のように書くだけで MPTCP 対応が完了するようになりました。これによって Go でも(リビルドは必要ですがほぼ)TCP と同じ利用方法で使えるので簡単に MPTCP が使えて便利だなと思いました。

lc := &net.ListenConfig{}
lc.SetMultipathTCP(true)
ln, err := lc.Listen(context.Background(), "tcp", *addr)

利用用途としても最近では非常に発達しています。よく知られてる Appleの利用例 以外にも OpenMPTCProuter というプロジェクトでは複数の回線を束ねて帯域を広げるのに MPTCP を利用したルーターを作ったりしています。

また、同じような発想の話で 5G のコンテキストでは ATSSS(Access Traffic Steering, Switching and Splitting)5と呼ばれる仕組みがあります。

3GPP 環境 (e.g. モバイル通信)と Non-3GPP 環境(e.g. Wi-Fi)の終端装置を UPF に直接入れることで、適切なリンクに合わせて処理を行います。

この話については むねあきさんが書かれた記事 が詳しいのでオススメします。

ATSSSのアーキテクチャ図。UPFの中にはMPTCPのProxyとPMF(Performance Measurement Function)があり、そのUPFで3GPP 環境と Non-3GPP 環境を終端して、DataNetworkとの通信を行っている
ATSSSのアーキテクチャ図6

それにしても PMF みたいなやつは、MPTCP なんで適切なスケジューラーを利用すれば問題ないのではないだろうか?みたいな気持ちがありますが、L3 の知見を L4 にフィードバックしたいということ何でしょうね。確かに L4 のレイヤで言われるより長い時間の統計を取って利用することで嬉しくなったりするかもなーとかは思うので気になるところです。

eBPFとは

eBPF(extended Berkeley Packet Filter) は、Linux カーネル内で実行されるプログラムを実行するための拡張可能な仕組みです。元々はネットワークパケットのフィルタリングに使用されていた Berkeley Packet Filter(BPF)を拡張したもので、現在ではさまざまな用途に広がっています。

eBPF は、プログラムを動的に挿入し、実行できる柔軟な仕組みです。これにより、カーネルの様々な部分で動作する小さなプログラムを実行できます。

struct_opsについて

BPF_STRUCT_OPS と呼ばれる特定のカーネル内関数ポインタを実装する仕組みがあります。これは、 Linux v5.3から入りました。 現在は TCP の輻輳制御(tcp_congestion_ops)を eBPF で記述する為に使われていることが知られています。 例えば Cubic と呼ばれる有名な輻輳制御アルゴリズムは現在は eBPF で記述されており、その例がkernelのリポジトリツリーに含まれています

このようにカーネルを弄らなくても輻輳制御アルゴリズムの実装をプラグインのように適用できるので、今日ではお手軽にアプリケーションの特性に合わせた通信環境を実装することが可能になりました。

そして、これを応用して今日では MPTCP のスケジューラーが eBPF で書けるようになりました。最初のサポートは Linux v5.19 から入りました(なお完全なサポートや最適化はまだ取り込まれてない)

つまり任意の評価アルゴリズムを書いて任意のサブフローに好きなようにパケットを流し込むといったことが簡単にできるようになったわけですね。

オレオレMPTCPスケジューラーをちょっと作ってみた

ではこのおもしろ技術に触れてみたいと考えるのが今日の本題です。少し触ってみた経験と実装に簡単な解説をつけつつ話して行きます。

今回は Lowest-RTT-First になるバージョンを実装してみました。ここで指す Lowest-RTT-First というのは SRTT が最小の subflow を選択するアルゴリズムとします。また今回は Upstream に入ってない mptcp_net-next の v6.6.0 を対象に説明していきます。

最小構成の例

ひとまず実装物の説明の前に mptcp_net-next という Upstream に入る前のカーネルに置かれている最小構成のスケジューラー実装である mptcp_bpf_first.c を利用して構造と利用法を説明します。

以下が最小構成であるスケジューラーのコードです。これは、ある subflow 1 つに対してのみパケットを投げ続けることができるスケジューラーです。

末尾に書いてある struct mptcp_sched_ops に関数ポインタを登録することで、実際にスケジューラーとして利用できます。

登録が必要なものは次の4つです

  • init: スケジューラーをロードした時にコールされる関数
  • release: スケジューラーをアンロードした時にコールされる関数
  • get_subflow: MPTCP のパケットを投げるのに呼ばれる関数(スケジューラー機能の main 関数部分に当たるようなところ)
  • name: sysctl を利用して利用するスケジューラーを決定するのでその時に渡す名前
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2022, SUSE. */

#include <linux/bpf.h>
#include "bpf_tcp_helpers.h"

char _license[] SEC("license") = "GPL";

SEC("struct_ops/mptcp_sched_first_init")
void BPF_PROG(mptcp_sched_first_init, struct mptcp_sock *msk)
{
}

SEC("struct_ops/mptcp_sched_first_release")
void BPF_PROG(mptcp_sched_first_release, struct mptcp_sock *msk)
{
}

int BPF_STRUCT_OPS(bpf_first_get_subflow, struct mptcp_sock *msk,
           struct mptcp_sched_data *data)
{
    mptcp_subflow_set_scheduled(bpf_mptcp_subflow_ctx_by_pos(data, 0), true);
    return 0;
}

SEC(".struct_ops")
struct mptcp_sched_ops first = {
    .init       = (void *)mptcp_sched_first_init,
    .release    = (void *)mptcp_sched_first_release,
    .get_subflow    = (void *)bpf_first_get_subflow,
    .name       = "bpf_first",
};

実際にこれを使う場合はどのようにするかというと、このようにして実行します。

# ebpfのプログラムロード
sudo bpftool struct_ops register mptcp_bpf_first.o
# sudo bpftool prog list とやると確認ができる

# mptcpのスケジューラーのロード
sudo sysctl -w net.mptcp.scheduler=bpf_first

これである任意の subflow 1 つのみにパケットを流すような実装ができました。

この仕組みは現在デフォルト機能になってるスケジューラーでも同様に mptcp_sched_ops に詰めてあげています。

該当箇所は この部分 です。

static int mptcp_sched_default_get_subflow(struct mptcp_sock *msk,
                       struct mptcp_sched_data *data)
{
    struct sock *ssk;

    ssk = data->reinject ? mptcp_subflow_get_retrans(msk) :
                   mptcp_subflow_get_send(msk);
    if (!ssk)
        return -EINVAL;

    mptcp_subflow_set_scheduled(mptcp_subflow_ctx(ssk), true);
    return 0;
}

これは、解説されてると有用なので、ざっくりデフォルトスケジューラーのプログラムの解説をします。

  • data->reinject: ここには今投げようとしてるデータが再送されるデータなのかどうかのフラグが含まれています。
  • mptcp_subflow_get_retrans: 再送の場合に使われる関数
    • アクティブなサブフローの中でTCP 送信待ちのデータがない場合を利用する
    • 利用できなければ、backup flag がついているエンドポイントを選ぶ
  • mptcp_subflow_get_send: 初めて投げられる時に使われる関数
    • linger time(キューがはけるまでの時間)が一番短いsubflowを使います。
      • sk_wmem_queued とソケットに書き込むバッファメモリが queue を示しています
      • このアルゴリズムは blest アルゴリズムを参考にして作られてるらしいです。
      • ペーサー(送信データのレートみたいなものです)なども含まれているので、ここが MPTCP の輻輳制御部分もやってそうです。

細かいことを知りたい場合は ここで呼ばれる mptcp_subflow_get_send 関数 に書いてあるので、MPTCP のスケジューラーを実装したい人は参考になりますので、一度読んでおくと良いです。

Lowest-RTT-First 対応スケジューラー

Smoothed RTT (SRTT)を利用して最小の RTT を見て動く簡単なやつを改造して作ってみました。SRTT というのはローパスフィルタが入った RTT みたいなものです。これの Linux 上での測定アルゴリズムについては このブログ が割とよくまとまっていますので気になる方はどうぞ。

で今回のコードのあるリポジトリは こちら です。これは、mptcp net-next の開発リポジトリに含まれてる mptcp_bpf_burst.c を改造したものです。

ざっくり説明すると、全ての subflow を探索して、利用可能な subflow の中で、なおかつ RTT の最小値を持つ subflow を優先して投げつけるということをしています。これにより RTT が良い subflow を貪欲に選択し続けるみたいな実装が書けました。

(実際には前述したデフォルトのスケジューラーのように、RTTベースだけではなく、ペーシングやqueueの容量などの複合要因を考えるのが良いというのが正解な気もしますが...w)

static int bpf_minrtt_get_send(struct mptcp_sock *msk,
                  struct mptcp_sched_data *data)
{
    struct mptcp_subflow_context *subflow;
    struct sock *sk = (struct sock *)msk;
    __u32 selected_minrtt = 0;
    __u32 selected_subflow_id = 0;
    __u32 minrtt = 0;
    struct sock *ssk;
    int i;

    for (i = 0; i < data->subflows && i < MPTCP_SUBFLOWS_MAX; i++) {
        subflow = bpf_mptcp_subflow_ctx_by_pos(data, i);
        if (!subflow)
            break;

        ssk = mptcp_subflow_tcp_sock(subflow);
        if (!mptcp_subflow_active(subflow))
            continue;

        const struct tcp_sock *tp = bpf_skc_to_tcp_sock(ssk);
        if (!tp){
            continue;
        }
        
        minrtt = tp->srtt_us;
        if (minrtt < selected_minrtt || (selected_minrtt == 0 && selected_subflow_id == 0)){
            selected_minrtt = tp->srtt_us;
            selected_subflow_id = i;
        }
    }
    mptcp_set_timeout(sk);

    subflow = bpf_mptcp_subflow_ctx_by_pos(data, selected_subflow_id);
    if (!subflow){
        return -1;
    }

out:
    mptcp_subflow_set_scheduled(subflow, true);
    return 0;
}

ということで、eBPF を利用して任意のアルゴリズムのスケジューラーを簡単に実装できました。

カーネルのドキュメントを眺めてみると bpf_prog_run に関して BPF_PROG_TYPE_STRUCT_OPS があるので、Unittest とかもしっかり書けそうだなぁというのも嬉しいポイントだと思いました。

引っかかったポイントは、既存実装に含まれていた bpf_tcp_helpers.hstruct tcp_sock のメンバがカーネル本体に含まれる tcp_sock と全然数が違ったことでした。それにより利用できるメンバが制限されていると思って途方に暮れていました。ですが実際に git bleam などで状況確認をしていくと、どうやら構造体の順番や数は関係なく、メンバのフィールド名が勝手に mapping されていたので、普通に利用したいフィールド名を tcp_sock に追加すれば良いとわかりました。この点でしばらくハマってしまっていました。(正直いまだによく分かってない)

それと普段 cilium/ebpf を利用して go で書いて開発してるのですが、その pure go な実装のローダーの上で BPF_PROG_TYPE_STRUCT_OPS が使えず普段使ってるもので動かず悲しい気持ちになりました。maptype はあるんですけどね...誰もやらなかったら試しに改造してパッチを出そうかなと思います。

終わりに

なぜ MPTCP の話をしたのかというと、SFC のとある博士課程の学生と一緒に研究開発をやっていて(thanks @yas-nyan)、その中で MPTCP に関する知見を得たりしたので論文に書かなかったこと含めてちょっと供養をしようと思ったからでした。

僕も博士受けたいと思っていますが、ネタを思いつけず困ってるので迷走してる感じではあります...:innocent:

個人的には次にちゃんと来る技術はマルチパス技術だろうなと思っており、ここ数年で MPTCP 技術の自由度と実装されてる品質が高くなったなと思っています。なので例えばポリシー投入が可能な SDN などの実装で今までにない世界を掘り下げられるのではないかと感じるようになりました。

例えば L3 の知見をもとに L4 を制御するとか、逆に L7 のセマンティクスを L4 にフィードバックするとか。eBPF でスケジューラ実装が書けるので eBPF Map を通じてならアプリケーションとの連携が比較的簡単です。今後こういうのを応用すると、DHCP や BGP 拡張との合わせ技でマルチパススケジューラーのアルゴリズムやトランスポート層の輻輳制御アルゴリズムをサーバーにフェッチさせて、アプリケーションやDCなどのネットワーク特性に合わせてアルゴリズム選択するなど、プロビジョニングの点でも面白いことが出来そうでワクワクしますよね(妄想)

皆さんも eBPF を使っておもしろスケジューラーを書いたりして楽しみましょう:)

参考文献

OSS による模擬フレッツ光網(IPoE・検討編)

この記事は,『BBSakura Networks Advent Calendar 2023』の 23 日目の記事です……が,遅刻しました! :dogeza:

はじめに

初めましての方は初めまして! そうでない方はこんにちは! BBSakura Networks 株式会社 事業本部の @paina こと佐藤です。

みなさんは,Advent Calendar 12 日目の記事「疑似フレッツ光網内の通信を accel-ppp で再現できるか検証する(検討編)」をご覧になりましたか。 その記事について,ひとつ皆様にお知らせしておきたいことがございます。

「疑似フレッツ光網〜」の記事を書かれた佐藤さんは
私とは別の佐藤さんです!

私の友人や技術者のコミュニティ,時には社内の方からも「paina さんの記事いいね!」というお言葉を頂いており,その度にアナザー佐藤さんに申し訳ない気持ちになっています。(笑)

その後,むしろ佐藤と佐藤をセット販売にしたほうが良いのではないか? という悪乗り……じゃない,共著案が立ち上がるまでに至りました。

Slack のスクリーンキャプチャ t-sato:佐藤あるある対応が大変なので、どっかのタイミングで共著にしましょう! (余力があれば)PPPoE IPv6 編、IPoE 編と続く予定です。 y-kusakabe:余計ややこしくなりそうw t-hayasaka: ばら売り不可セット販売 マスター佐藤
佐藤セット販売のお知らせ

というわけで,今回私は将来の佐藤 & 佐藤の共著を目指して,IPoE を中心にフレッツ光網を模擬する環境を検討してみました。

なぜ模擬フレッツ光網が必要か

弊社および BBIX では,「OCX 光 インターネット」という,フレッツ光を利用した法人向けインターネット接続サービスを提供しています(10 ギガ版プレスリリース1 ギガ版プレスリリース)。 私もこのサービスの開発に少し関わっているのですが,IPoE 版の模擬フレッツ光網はその開発過程で立ち上げたシステムです。

本サービスでは CPE (Customer Premises Equipment) として NTT 東日本・西日本のレンタルのホームゲートウェイ(以下,HGW)をお客様にご利用いただく場合があるのですが, この場合に IPoE と IPv4 over IPv6 の通信を実現するには,事業者が HGW のためのソフトウェアを開発する必要があります。 本番環境では,そのソフトウェアは「フレッツ・ジョイント」という NTT 東西のサービスを用いて各お客様宅の HGW に配信され, 回線からの情報とも連携して IPoE・IPv4 over IPv6 の通信を確立します。

しかし,ソフトウェアの開発時にはまだその回線,つまり自社のサービスがなく,HGW のソフトウェアをデバッグすることが難しい段階もありました。 そのため,私たちは都内某所の検証ラボに IPoE 版の模擬フレッツ光網を構築して HGW のソフトウェア開発を行っていました。 今回この記事で述べる模擬フレッツ光網は,その環境を元に再構成したものです。 この事情から,この模擬フレッツ光網は UNI (User-Network Interface) の視点で本物のフレッツ光網に似た動作をできることを主眼としています。

OSS での再構成

検証ラボに構築した模擬フレッツ光網は,その一部にメーカー製品を使用しています。特にルータ等のネットワーク機器です。 そういったプロプライエタリ製品を利用した環境をそのまま解説するだけでは,気軽に作れるものではなくなってしまいます。 そこで,この記事ではほぼ全ての要素を OSS で実現できるよう,改めて構成を考えました。 しかし,今回はその構成を検討するのみで,十分な動作確認はできていません。 今後,実際に CPE を接続してみたりして,本当に模擬できているか確認し,「実装編」をお送りしたいと思います。

フレッツ光の回線種別について

フレッツ光に必要な要素を考える前に,回線種別について整理します。 フレッツ光では,RA (Router Advertisement) で /64 のプレフィクスを配る回線と, DHCPv6-PD で通常 /56 のプレフィクス*1を配る回線があります。 前者を RA 回線・後者を PD 回線と呼んだりします。どちらの回線になるかは,下記の表に従います。

RA 回線・PD 回線の場合分け

フレッツ光ネクスト フレッツ光クロス
NTT 東日本管内 ひかり電話契約なし RA PD
ひかり電話契約あり PD PD
NTT 西日本管内 PD PD

RA 回線は場合分けの上では NTT 東日本管内・ひかり電話契約あり・フレッツ光ネクストの回線のみのパターンではありますが,そのユーザは多いようです。 今回は RA 回線を模擬するかたちで,構成を検討しました。

ネットワーク構成

まず,ネットワークの全体像を示します。

「収容ルータ VyOS」を中心にユーザネットワークが 2001:db8:817:1::/64・2001:db8:817:2::/64・link-local only でつながっている。前者 2 つが USER1・USER2 の UNI (RA) で,後者は USER3 UNI (PD) で今後検討となっている。収容ルータにはさらに IPv6 Internet と,2001:db8:817::/64 のリンクを介して「各サービス用 FreeBSD ホスト」がつながっている。ホストには「VNE DNS キャッシュサーバ : Unbound」・「SNTP サーバ : ntpd」・「DHCPv6 サーバ : isc-dhcp」・「HTTP 経路サーバ : Nginx 」がインストールされている。
模擬フレッツ光 ネットワーク構成

ごらんの通りあまり複雑な構成は必要ありません。 今回は UNI の視点でフレッツ光網を模擬しているので,CPE に対して適切なプロトコルで情報を与えて通信を確立できればよいからです。 必要なものは,何かしらの IPv6 インターネットへのリーチャビリティと,VyOS のホスト,FreeBSD のホストで,それらは仮想基盤の上に構築してもベアメタル PC を組み合わせてもよいです。

ソフトウェア構成・設定例

次に,使用するソフトウェアとそれが担う機能,設定例などを示します。

サービスホスト : FreeBSD

各ソフトウェアを提供するために,Unix 系 OS のホストが必要です。 Linux でもよいのですが,私はちょっとした検証にはネットワークに関する設定が簡単にできる FreeBSD を利用することも多いです。 rc.conf を下記のように設定し,アドレスやサービスの立ち上げを行います。

/etc/rc.conf

hostname="EXP-FLETS-SV01"
ifconfig_vmx0="up"  # vmx0: 検証ネットワークへ接続するインターフェイス
ifconfig_vmx0_ipv6="inet6 2001:db8:817::3/64"  # vmx0 に設定する IPv6 アドレス

ifconfig_vmx1="DHCP"  # マネジメント等へのアクセスは別のインターフェイスで設定

ifconfig_lo0_alias0="inet6 2404:1a8:7f01:b::3/128"  # 模擬 DNS キャッシュサーバのアドレス #1
ifconfig_lo0_alias1="inet6 2404:1a8:7f01:a::3/128"  # 模擬 DNS キャッシュサーバのアドレス #2
ifconfig_lo0_alias2="inet6 2404:1a8:1102::b/128"  # 模擬 SNTP サーバのアドレス #1
ifconfig_lo0_alias3="inet6 2404:1a8:1102::a/128"  # 模擬 SNTP サーバのアドレス #2
ifconfig_lo0_alias4="inet6 2404:1a8:c023:3201::15/128"  # 模擬 HTTP 経路サーバのアドレス

ipv6_route_0="-inet6 2001:db8:817::/48 2001:db8:817::2"  # ユーザ向けのスタティックルート

ntpd_enable="YES"  # ntpd を起動 (模擬 SNTP キャッシュサーバ)
unbound_enable="YES"  # Unbound を起動 (模擬 DNS キャッシュサーバ)
dhcpd6_enable="YES"  # isc-dhcp-server を起動 (DHCPv6 サーバ)

収容ルータ : VyOS

収容ルータは VyOS で模擬します。 まず,IPv6 インターネットへの到達性を RA を受けるなどして確保します。 模擬のユーザに割り当てるアドレスがグローバルなものでない場合は,NAT66 でインターネットに到達できるようにしておくと良いでしょう。

set interfaces ethernet eth0 ipv6 address autoconf
set nat66 source rule 1000 source prefix '2001:db8:817::/48'
set nat66 source rule 1000 translation address 'masquerade'

サービスホストとのリンクのアドレスを設定し,サービスのアドレスへのスタティックルートを設定します。

set interfaces ethernet eth1 address '2001:db8:817::2/64'
set protocols static route6 2404:1a8:7f01:a::3/128 next-hop 2001:db8:817::3
set protocols static route6 2404:1a8:7f01:b::3/128 next-hop 2001:db8:817::3
set protocols static route6 2404:1a8:1102::a/128 next-hop 2001:db8:817::3
set protocols static route6 2404:1a8:1102::b/128 next-hop 2001:db8:817::3
set protocols static route6 2404:1a8:c023:3201::15/128 next-hop 2001:db8:817::3

ユーザ向けのインターフェイスにアドレスをつけ,RA と DHCPv6 でアドレス等の情報を配布するようにします。

set interfaces ethernet eth2 address '2001:db8:817:1::fffe/64'
set interfaces ethernet eth3 address '2001:db8:817:2::fffe/64'
set service dhcpv6-relay listen-interface eth2
set service dhcpv6-relay listen-interface eth3
set service dhcpv6-relay upstream-interface eth1 address '2001:db8:817::3'
set service router-advert interface eth2 prefix 2001:db8:817:1::/64
set service router-advert interface eth3 prefix 2001:db8:817:2::/64

DHCPv6 サーバ : isc-dhcp-server

PD 回線で DHCPv6-PD にてプレフィックスを委譲し,また PD 回線と RA 回線の両方で DNS キャッシュサーバのアドレスなどを配布する,DHCPv6 サーバです。 DHCPv6 サーバには,WIDE Project による実装や,ISC による実装 isc-dhcp,同じく ISC による Kea DHCP Server などがあります。今回は一般によく使われておりシンプルな isc-dhcp を使用しました。 DHCPv6 はユーザ収容を行う VyOS でもサポートしていますが,細かい制御を行うために VyOS は DHCPv6 Relay とし DHCPv6 Server は別途立ち上げました。

今回は RA 回線を模擬しますので,設定は次のようになります。

/usr/local/etc/dhcpd6.conf

option dhcp6.name-servers 2404:1a8:7f01:b::3, 2404:1a8:7f01:a::3;
option dhcp6.domain-search "flets-east.jp", "iptvf.jp";
option dhcp6.sntp-servers 2404:1a8:1102::b, 2404:1a8:1102::a;

subnet6 2001:db8:817:1::/64 {}
subnet6 2001:db8:817:2::/64 {}

模擬 VNE DNS キャッシュサーバ : Unbound

VNE が提供する DNS キャッシュサーバです。キャッシュサーバとして一般的な実装の Unbound を使用しました。 後述する HTTP 経路情報サーバなど,フレッツ光網内のみで利用されるドメイン名を local-data として宣言しておくとよいでしょう。

/usr/local/etc/unbound/local-data.conf

server:
        local-data: "route-info.flets-east.jp 10m AAAA 2404:1a8:c023:3201::15"

SNTP サーバ: ntpd

フレッツ光の DHCPv6 で配布される SNTP サーバです。NTP サーバのリファレンス実装である ntpd の FreeBSD に付属するバージョンを使用しました。 ntpd はフルセットの NTP だけでなく SNTP にも対応しているので,そのまま利用可能です。 FreeBSD の ntpd は rc.confenable するだけでクエリを受け付けるようになるので ntp.conf の設定は不要と思います。

HTTP 経路情報サーバ: Nginx

フレッツ光には,各 VNE が利用しているプレフィックスの一覧を取得する,経路情報サーバが存在します。 実態としては HTTP サーバで,NTT 東日本管内では下記のように curl 等でアクセスできます。

curl -H 'Connection: close' http://route-info.flets-east.jp:49881/v6/route-info

一部の CPE 製品はこれにアクセスして自身に割り当てられたアドレスを検索することがありますので,これも準備しておくとよいです。 模擬 VNE DNS キャッシュサーバに設定した AAAA レコードのアドレスの tcp/49981 で Nginx を立ち上げると模擬できます。

/usr/local/etc/nginx/nginx.conf

http {
    # (snip)
    server {
        listen [::]:49881;
        server_name route-info.flets-east.jp;

        location / {
            root /var/www/route-info.flets-east.jp;
        }
    }
}

あとは curl 等で取得した情報をファイルとして /var/www/route-info.flets-east.jp/v6/route-info に書いて置きます。 デバッグのために適宜編集してもよいでしょう。

まとめ

この記事では,フレッツ光網とその RA 回線を模擬するために,OSS で下記の機能を実現する検討をしました。

  • 回線への RA・DHCPv6 でのアドレス等の配布
  • 模擬 VNE DNS キャッシュサーバ
  • 模擬 SNTP サーバ
  • 模擬 HTTP 経路情報サーバ

今後は下記のようにさらに詳細化を進めて,「実装編」の記事の公開を目指してみます。佐藤 & 佐藤共著で!

  • この環境に実際に CPE を接続して機能不足等なく模擬できているか確認する
  • PD 回線も模擬できる構成を検討する
  • IPv4 over IPv6 も模擬し IPv4 でも通信できるようにする
    • MAP-E や DS-Lite 等のソフトウェアを調査する必要あり

宣伝コーナー

  • 弊社と BBIX では,フレッツ光を利用したインターネット接続サービス「OCX 光 インターネット」を提供しています。ご検討ください。
  • この記事を詳細化したものを,コミックマーケット103で頒布するかもしれません。
    • コミックマーケットへの参加,及び文書の頒布は業務外ですので,詳細は私の X/Twitter アカウントでご確認ください。

参考

*1:一部,もっと短いプレフィクスを配る回線があるそうですが,現存するかは不明です