Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
JANOG42 GoでEPC作って本番運用している話 / JANOG42 EPC Writte...
Search
Yuya Kusakabe
August 27, 2018
Technology
0
130
JANOG42 GoでEPC作って本番運用している話 / JANOG42 EPC Written in Go in Production
JANOG42 Meeting in Mie で発表した資料です。
https://www.janog.gr.jp/meeting/janog42/program/goepc
Yuya Kusakabe
August 27, 2018
Tweet
Share
More Decks by Yuya Kusakabe
See All by Yuya Kusakabe
XDPによるトラフィックジェネレータの話 - eBPF Meetup Japan #4/XDP Traffic Generator
higebu
0
24
XDPのテストとCI / XDP Testing and CI
higebu
1
640
モバイルネットワークのデータプレーンをXDPで作る話 / XDP based Mobile Network Data Plane
higebu
1
1.8k
JANOG45 パケット処理の独自実装や高速化手法の比較と実践 独自パケット処理の実装方法の解説(XDP) / JANOG45 Packet Forwarding with XDP
higebu
0
24
2018/01/24 セキュアモバイルコネクトの裏側 さくらの夕べ in すごい広島 / 20180124 SAKURA Secure Mobile Connect Deep Dive
higebu
1
8k
Other Decks in Technology
See All in Technology
なぜテストマネージャの視点が 必要なのか? 〜 一歩先へ進むために 〜
moritamasami
0
210
CDK CLIで使ってたあの機能、CDK Toolkit Libraryではどうやるの?
smt7174
4
100
新アイテムをどう使っていくか?みんなであーだこーだ言ってみよう / 20250911-rpi-jam-tokyo
akkiesoft
0
150
LLMを搭載したプロダクトの品質保証の模索と学び
qa
0
1k
Terraformで構築する セルフサービス型データプラットフォーム / terraform-self-service-data-platform
pei0804
1
150
JTCにおける内製×スクラム開発への挑戦〜内製化率95%達成の舞台裏/JTC's challenge of in-house development with Scrum
aeonpeople
0
190
生成AIでセキュリティ運用を効率化する話
sakaitakeshi
0
510
Platform開発が先行する Platform Engineeringの違和感
kintotechdev
4
540
Kiroと学ぶコンテキストエンジニアリング
oikon48
6
9.9k
ハードウェアとソフトウェアをつなぐ全てを内製している企業の E2E テストの作り方 / How to create E2E tests for a company that builds everything connecting hardware and software in-house
bitkey
PRO
1
120
AIエージェント開発用SDKとローカルLLMをLINE Botと組み合わせてみた / LINEを使ったLT大会 #14
you
PRO
0
100
dbt開発 with Claude Codeのためのガードレール設計
10xinc
2
1.1k
Featured
See All Featured
Building Applications with DynamoDB
mza
96
6.6k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
656
61k
Visualization
eitanlees
148
16k
GraphQLとの向き合い方2022年版
quramy
49
14k
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
15
1.6k
How STYLIGHT went responsive
nonsquared
100
5.8k
Git: the NoSQL Database
bkeepers
PRO
431
66k
Music & Morning Musume
bryan
46
6.8k
Side Projects
sachag
455
43k
Bash Introduction
62gerente
615
210k
How to Think Like a Performance Engineer
csswizardry
26
1.9k
jQuery: Nuts, Bolts and Bling
dougneiner
64
7.9k
Transcript
GoでEPC作って本番運用している話 JANOG42 Meeting in Mie 発表日時:7月12日(木) 15:05~15:35(30分) 発表会場:多目的ホール 2018/7/12(木) (C)
Copyright 1996-2018 SAKURA Internet Inc さくらインターネット株式会社 IoTチーム 日下部雄也
自己紹介 2 日下部 雄也 https://twitter.com/higebu https://github.com/higebu • さくらインターネット2年目(2社目) • さくらのセキュアモバイルコネクト
◦ HSS/PGWの開発 ◦ SIMのプロファイル作成 • 好きなルータ ◦ VyOS • 好きな言語 ◦ Go
この話をしようと思った理由 • EPCの実装について話せる仲間が欲しい • うちではこうしていますみたいな話が聞きたい • EPCを実装する人が増えて欲しい • 5GCではControl PlaneがOpenAPI
3.0になるらしいので、作 る人増えそう 3
アジェンダ • さくらのセキュアモバイルコネクトとは • なぜ独自にHSS、PGWを作ったのか • なぜGoで作ったのか • 基本的なLTEのアーキテクチャ •
HSSの基本 • Goを使ったHSSの作り方 • PGWの基本 • Goを使ったPGWの作り方 • まとめ 4
さくらのセキュアモバイルコネクトとは • お客様のデバイスからインターネットを経由しない 閉域網でさくらのクラウドと通信できるサービス • SIM1枚当たり12円/月 • 何回でもSIMを登録解除可能で、解除中は0円 • 詳しくは
https://www.sakura.ad.jp/services/sim/ 5
さくらのセキュアモバイルコネクトとは 6 専用サーバー データセンター AWS など MNO インターネット (オプション) スイッチ
ネットワーク接続 オプション サーバ モバイルゲートウェイ さくらのSIMを入れた デバイス
なぜ独自にHSS、PGWを作ったのか 7
なぜ独自にHSS、PGWを作るのか • 面白いから • コスト削減 • ◦億円削減 • 機能追加の自由度 •
SIMルートとか • 今後も便利な機能を作っていく予定 • アンコントローラブルな箇所の削減 • 性能、品質を自分たちでコントロールできる • 何かあったとき自分たちで対応できる • 今までの常識を壊したかった 8
なぜGoで作ったのか 9
なぜGoで作ったのか • 趣味 • シンプルな言語仕様 • ネットワーク強いけどプログラミング初心者な人とかでもすぐに書けるようにな る • gofmtによる自動フォーマット
• それなりに高速 • go bench でベンチマークしやすい • 豊富なサンプル • Go自体、github.com/miekg/dns 、 github.com/osrg/gobgp など 10
基本的なLTEのアーキテクチャ 11
基本的なLTEのアーキテクチャ 12 詳細は 3GPP TS 23.401 参照 eNB MME SGW
PGW HSS UE S1-MME S1-U S5 S6a SGi S11 LTE-Uu Operator Network Diameter/SCTP C: GTPv2-C/UDP U: GTPv1U/UDP
基本的なLTEのアーキテクチャ - ローミング 13 詳細は 3GPP TS 23.401 と GSMA
IR.88 参照 eNB MME SGW PGW HSS UE S1-MME S1-U S8 S6a SGi S11 LTE-Uu Operator Network VPLMN HPLMN
基本的なLTEのアーキテクチャ - 処理の流れ • 例)Attach procedure • 3GPP 23.401 5.3.2.1
E-UTRAN Initial Attach • こういう図がたくさんあるので、 これで流れを把握する 14
HSSの基本 15
HSSの基本 - プロトコル • 3GPP TS 23.401 5.1.1.9 参照 •
SCTP(Stream Control Transmission Protocol) • RFC 4960 • port 3868 • Diameter • RFC 3588 • Diameterプロトコルガイド(本) 16 Figure 5.1.1.9-1: Control Plane for S6a interface 3GPP TS 23.401
HSSの基本 - 保持しないといけないデータ • 3GPP TS 23.401 5.7.1 参照 •
5.7は Information Storage という章で、それぞれのコンポー ネントが何を保持しないといけないか書いてある • IMSI、MME Identity、APNなど • ここには書いていないが、AuCも実装しないといけないので、 Rand、Kiなども保存する必要がある • AuCは認証に使う • LTEのセキュリティについて詳しくは 3GPP TS 33.401 参照 17
HSSの基本 - MMEとのやり取り(S6a) • 全体の流れが23.401、動作の詳細は29.272に書いてある • 3GPP TS 23.401 の下記の章参照
• 5.3 Authentication, security and location management • 5.4 Session Management, QoS and interaction with PCC functionality • 5.5 Handover • 3GPP TS 29.272 の下記の章参照 • 5 MME – HSS (S6a) and SGSN – HSS (S6d) • 7 Protocol Specification and Implementation • ここからいろいろなドキュメントに飛ばされる。。。 18
HSSの基本 - MMEとのやり取り(S6a) • 少なくとも下記のCommandに対応する必要がある • Authentication Information • Initial
Attach • Update Location • Initial Attach • Cancel Location • HSSからのDetach • Notify • MMEやSGWの変更時など • Purge UE • MME上のSubcription-Dataが消えるときに来る 19
HSSの基本 - MMEとのやり取り(S6a) • Authentication Informationでは AuC を作ってSIMの認証を する必要がある •
鍵交換アルゴリズムは Milenage(3GPP TS 35.205) • MilenageはFreeBSDに実装されていて参考になる • https://github.com/freebsd/freebsd/blob/master/contrib/wpa/src/crypto/milenage.c 20
Goを使ったHSSの作り方 21
Goを使ったHSSの作り方 - GoでSCTP • Linuxはわりと古くからSCTP使える • 詳しくは man sctp •
one-to-many と one-to-one があり、 one-to-one の方はTCPと同様のAPIで 使える • one-to-many できない環境なので one-to-one を採用 • SCTPにはいろいろなパラメータがあるが、GSMA IR.88におすすめ設定が 載っている • Go本体はSCTPに対応していない • Go自体に機能追加するか、 github.com/ishidawataru/sctp を使う 22
Goを使ったHSSの作り方 - GoでSCTP • さくらではGo自体に機能追加した • Go1.9.1時点でのソース は公開している • GoへのPR:
proposal: x/net/sctp: new package #22191 • Go本体に追加しようとしたが、SCTPはマイナーなので golang.org/x/net に してと言われ、さらに他のIssueの対応待ちで保留になっている 23 ln, err := net.Listen("sctp", ":3868") if err != nil { // handle error }
Goを使ったHSSの作り方 - GoでDiameter • github.com/fiorix/go-diameter を使っている • わりとメンテされているし、動く • XMLでCommand、AVPの定義を書くスタイル(つらい)
• 2018/2/6に Adding Go-Diameter SCTP support and 3GPP S6a protocol support #78 というPRがマージされている • github.com/ishidawataru/sctp が使われている • さくらでは未検証 • 試してみたい気持ちはあるが、Purge-UEなど足りないCommandがある 24
Goを使ったHSSの作り方 - GoでDiameter • 正しいパケットが作れているかの確認はWiresharkでやる 25
Goを使ったHSSの作り方 - GoでDiameter • 正しいパケットだからと言って動くとは限らない • ianaの定義と被っているResult Code • 足りないAVP
• Mbit • 相手の運用上指定できない数値 • なぜか通らないAVP 26
PGWの基本 27
PGWの基本 - Control Plane プロトコル • 概要は 3GPP TS 23.401
5.1.1.6 • 詳細は 3GPP TS 29.274 • GTPv2-C (2123/UDP) 28 Figure 5.1.1.6-1: Control Plane for S5 and S8 interfaces 3GPP TS 23.401 3GPP TS 29.274
PGWの基本 - User Plane プロトコル • 概要は 3GPP TS 23.401
5.2.1.1 • 詳細は 3GPP TS 29.060 • GTPv1-U (2152/UDP) 29 Figure 5.1.2.1-1: User Plane 3GPP TS 23.401 Figure 2: Outline of the GTP Header 3GPP TS 29.060
PGWの基本 - 保持しないといけないデータ • リストは 3GPP TS 23.401 5.7.4 •
どう使うかは 3GPP TS 29.274 • IMSI、IMEI、IPアドレスなど 30
PGWの基本 - SGWとのやり取り(S5/S8) • 全体の流れが23.401、動作の詳細は 29.274 に書いてある • 3GPP TS
23.401 の下記の章参照 • 5.3 Authentication, security and location management • 5.4 Session Management, QoS and interaction with PCC functionality • 5.5 Handover • 3GPP TS 29.274 の全部参照 • ここからいろいろなドキュメントに飛ばされる。。。 31
PGWの基本 - SGWとのやり取り(S5/S8) • Control Planeは下記の5つを実装しておけば良いはず • Echo Request/Response •
SGWとの相互監視のため • Create Session Request/Response • Attachのため • Modify Bearer Request/Response • SGWの変更を伴うハンドオーバーのため • Delete Session Request/Response • Dettachのため • Delete Bearer Request/Response • PGWからベアラを削除するため 32
PGWの基本 - SGWとのやり取り(S5/S8) • User PlaneはGTPv1-Uの下記のMessage Typeに対応する 必要がある • Echo
• SGWとの相互監視のため • G-PDU • UEからのパケット、UEへのパケットを通すため 33
Goを使ったPGWの作り方 34
Goを使ったPGWの作り方 - GoでGTPv2-C • GoでGTPv2-Cを実装しているOSSを見たことはない • 普通にUDPサーバ、クライアントを実装すれば良い • golang.org/pkg/net で十分
• とにかくたくさんのIE(Information Element)のパーサを書か ないといけない(つらい) 35
Goを使ったPGWの作り方 - GoでGTPv2-C • 正しいパケットを作れているかはWiresharkで確認 36
Goを使ったPGWの作り方 - GoでGTPv2-C • 正しいパケットだからと言って動くとは限らない2 • 足りないIE • Instance •
PCO、3GPP TS 24.008に書いてあるけど 37
Goを使ったPGWの作り方 - GoでGTPv1-U • Linux kernel 4.7以降のgtpモジュールを使うか、tunインター フェースを作って実装するのが簡単 • 現在はtunインターフェース使う方で動いている
• 最近、 github.com/google/gopacket にGTPのパーサが追加 された • New protocol GTP #417 • 使ってはいないけど参考になるのでは 38
Goを使ったPGWの作り方 - GoでGTPv1-U • Linux kernel 4.7以降のgtpモジュールを使う場合 • netlink経由でgtpトンネルを作ることができる •
github.com/vishvananda/netlink を使うのが簡単 • 2017/5/7から使えるようになっている • Add support for GPRS Tunnelling Protocol(GTP) #229 • サンプルコード • さくらではこれより前から実装していたので、gtpモジュールの元になった libgtpnl を参考に実装した • netlinkのデバッグは大変だが nltrace が便利だった 39
Goを使ったPGWの作り方 - GoでGTPv1-U • tunインターフェースを使う場合(流れ) • Uplink • SGWから2152/UDPに来たGTPv1-Uのパケットのペイ ロードをtunインターフェースに入れる
• Downlink • tunインターフェースから読み込んだパケットをGTPv1-Uで カプセリングしてSGWに投げる 40
Goを使ったPGWの作り方 - GoでGTPv1-U • tunインターフェースを使う場合(実装) • SGW方面はただのUDPサーバ、クライアント • github.com/vishvananda/netlink でtunインターフェースを
作って読み書きする 41 tun PGW UDP socket S5/S8 SGi Uplink Downlink
Goを使ったPGWの作り方 - GoでGTPv1-U • tunインターフェースを使う場合(実装) • github.com/vishvananda/netlink でtunインターフェース 42 link
:= &netlink.Tuntap{ LinkAttrs: netlink.LinkAttrs{Name: "gtp0"}, Mode: netlink.TUNTAP_MODE_TUN, Flags: netlink.TUNTAP_DEFAULTS | netlink.TUNTAP_NO_PI, Queues: 1, } if err := netlink.LinkAdd(link); err != nil { // handle error } if err := netlink.LinkSetUp(link); err != nil { // handle error } • link.Fds が []*os.File になっているので、 link.Fds[0] をRead/Writeする
Goを使ったPGWの作り方 - GoでGTPv1-U • 性能について • 高負荷な状況ではコンテキストスイッチが問題になる • sendmmsg/recvmmsg 使うとppsが改善できる
• 詳しくはCloudflare先生の How to receive a million packets per second • Goだと golang.org/x/net/ipv4 でできる • サンプルコード • GTPのルータで使っている • モバイルゲートウェイではtunインターフェース側がボトルネックになる • 今のところそこまで困っていない 43
Goを使ったPGWの作り方 - GoでGTPv1-U • 参考: さくらのクラウド上での性能測定結果 • CPU 20 core、224
GB RAM、10Gbps • 2台のサーバ間でgtpトンネルを作ってiperf(iperf 3.2) • UDP(32 byteのパケット) • gtpモジュール: ~150Kpps • Go実装: ~70Kpps • TCP • gtpモジュール: ~3Gbps • Go実装: ~1.5Gbps 44
Goを使ったPGWの作り方 - GoでGTPv1-U • 1台で数Gbps以上出す必要が出てきたら試さないといけない かなと思っているものたち • 独自カーネルモジュール • DPDK
• XDP • FD.io • 他に良さそうなものがあったら教えてください 45
まとめ 46
まとめ • EPCは案外作れるので皆さんも作りましょう • 作っている方がいたら声をかけてください 47
参考資料 • RFC • RFC 4960 SCTP • RFC 3588
Diamter • 3GPP • 3GPP TS 23.401 • 3GPP TS 24.008 • 3GPP TS 29.272 • 3GPP TS 29.274 • 3GPP TS 33.401 • 3GPP TS 35.205 • GSMA • GSMA IR.88 48 • Go • github.com/ishidawataru/sctp • github.com/fiorix/go-diameter • github.com/vishvananda/netlink • golang.org/x/net/ipv4 • C • Milenage • libgtpnl • nltrace
おまけ: 参考になるOSSのEPC実装 • http://www.openairinterface.org/ • CでEPC全部実装しているがSPGWになっている • 日本だと富士通さんがコアメンバー • https://github.com/travelping/ergw
• ErlangでGGSN/PGW実装している • http://nextepc.org/ • CでMME,SGW,PGW,HSS,PCRFを実装している 49