Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Accelerating TCP/IP Communications in Rootless Containers by Socket Switching

Accelerating TCP/IP Communications in Rootless Containers by Socket Switching

SWoPP22022 7/27 OS-3

松本直樹

July 27, 2022
Tweet

More Decks by 松本直樹

Other Decks in Research

Transcript

  1. Accelerating TCP/IP Communications
    in Rootless Containers by Socket Switching
    SWoPP2022 7/27 OS-3
    松本 直樹(京都大学), 須田 瑛大(NTTソフトウェアイノベーションセンタ)
    SWoPP2022 7/27 OS-3 1
    2022/7/27

    View Slide

  2. 本研究の背景
    コンテナランタイム自体の脆弱性→ランタイムを介した不正操作
    “Rootless Container”
    • ランタイム自体をroot権限(特権)なしで動かすことでセキュリティリスク
    を軽減
    • ネットワークはモジュール(slirp4netns, RootlessKit)により非特権化
    → 性能(スループット)が低いという問題
    SWoPP2022 7/27 OS-3
    2
    ホスト
    コンテナ





    veth
    デバイス
    要特権!
    ※veth: ペアで構成される仮想的なL2インタフェース
    2022/7/27

    View Slide

  3. 本研究の提案
    Rootless Container における通信性能を改善するbypass4netnsを提案
    • コンテナ内のソケットをホスト上のソケットに差し替え(Socket Switching)
    • 通信がボトルネックとなるモジュールを経由しないことで改善
    SWoPP2022 7/27 OS-3 3
    2022/7/27

    View Slide

  4. 本研究の成果
    bypass4netns により、スループットが向上することを確認
    • 特に、外部への通信については顕著な改善がみられる
    SWoPP2022 7/27 OS-3 4
    38.6 39.2
    0.452
    35.8
    41.4 39.8
    0
    10
    20
    30
    40
    50
    Container → Host Host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    2022/7/27

    View Slide

  5. Rootless Container について
    コンテナランタイム自体に脆弱性がある場合がある
    • Docker CVE-2014-9357
    悪意のあるコンテナが任意のバイナリを特権で実行可能
    • runc CVE-2016-3697
    悪意のあるコンテナが意図しないUIDで動作可能
    → ランタイム自体の脆弱性により、特権で不正な操作が可能になる可能性
    ランタイム自体を非特権で動かす→ Rootless Container
    • ランタイム自体が一般ユーザー権限で動作する
    • 脆弱性があった場合、被害範囲を小さくできる
    SWoPP2022 7/27 OS-3 5
    2022/7/27

    View Slide

  6. Rootless Container におけるネットワーク処理
    UserNS(UserNamespaces) を用いて、非特権化を実現
    ※UserNS: NS内の特権ユーザーをNS外の一般ユーザーにマップする
    • ランタイムのおおよその機能は UserNS でカバー
    ネットワークに関して、vethデバイスはホスト側の特権を要する
    → veth を利用しない手法でネットワークの非特権化を実現
    • slirp4netns: コンテナ内→外部の通信を担当
    • RootlessKit port driver: 外部→コンテナ内の通信を担当
    SWoPP2022 7/27 OS-3 6
    2022/7/27

    View Slide

  7. Rootless Container におけるネットワーク処理
    slirp4netns: コンテナ内からホスト外部への通信を中継
    • コンテナネットワークを扱う 内部 NetNS に TAPデバイスを作成
    • TAPデバイスを利用して、内部 NetNS から外部への通信を中継
    SWoPP2022 7/27 OS-3 7
    ホスト
    slirp4
    netns
    内部 NetNS
    コンテナ
    コンテナ




    TAP デバイスを作成し、
    TAP のファイルディスクリプタ
    をホスト側の slirp4netns に渡す
    TAP デバイスから受け取った
    パケットを取得し送信
    TAP
    パケット
    veth
    veth
    2022/7/27

    View Slide

  8. Rootless Container におけるネットワーク処理の問題点
    Rootless Container のネットワークの問題点
    • 性能の劣化(slirp4netns で顕著)
    SWoPP2022 7/27 OS-3 8
    38.6 39.2
    0.452
    35.8
    0
    5
    10
    15
    20
    25
    30
    35
    40
    45
    Container → Host Host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns
    2022/7/27

    View Slide

  9. 2022/7/27
    Rootless Container におけるネットワーク処理の問題点
    性能劣化の原因
    TCPパケットを再構築し、ソケットから送信するオーバーヘッド
    SWoPP2022 7/27 OS-3 9
    パケットA
    パケットα
    パケット1
    パケットB
    パケット2
    パケットβ
    dstIP: 192.168.1.1, dstPort: 443
    dstIP: 151.101.66.132, dstPort: 443
    dstIP: 133.3.250.189, dstPort: 443
    slirp4netns
    ソケット
    ソケット
    ソケット
    192.168.1.1:443 に connect
    slirp
    TCPパケットを再構築し、
    ペイロードを取得する
    TAP fd
    151.101.66.132:443 に connect
    133.3.250.189 :443 に connect

    View Slide

  10. 本研究における提案手法
    コンテナ内のソケットをホスト上のソケットへ差し替える(Socket Switching)
    • 外部へ/外部からの通信が対象(コンテナ間の通信はvethで行われるため対象外)
    • Socket Switching には Seccomp を利用
    → コンテナランタイムに対する大きな改変なく実現可能
    10
    2022/7/27

    View Slide

  11. Seccomp について
    Seccomp(Secure computing mode)
    プロセスで呼び出される syscall を制御するモジュール
    2種類の制御方式が存在する
    • 静的なプロファイルに基づく制御
    • Docker 等で用いられる手法
    • syscall ごとに挙動をプロファイルとして事前に指定しておく
    • syscall 呼び出し毎に動的に判断する制御
    • Seccomp User-space Notification(Seccomp Notify)
    • bypass4netns で利用
    SWoPP2022 7/27 OS-3 11
    2022/7/27

    View Slide

  12. Seccomp Notify について
    Seccompにおいて動的にsyscallを制御する
    • 監視プロセスで実行される syscall の読み取りや実行判断を行う
    SWoPP2022 7/27 OS-3 12
    2022/7/27

    View Slide

  13. Seccomp による Socket Switching
    Seccomp Notify を利用した Socket Switching
    • SECCOMP_IOCTL_NOTIF_ADDFD を利用
    SWoPP2022 7/27 OS-3 13
    2022/7/27

    View Slide

  14. bypass4netns での挙動
    Seccomp Notify を利用し接続先に応じて Socket Switching
    • コンテナ内のソケットと同じ設定のソケットをホスト上に作成する必要
    SWoPP2022 7/27 OS-3 14
    socket
    setsockopt
    connect
    socket
    setsockopt
    bypass4netns
    send
    ソケットの作成
    設定の反映
    Socket
    Switching
    設定を記録
    コンテナ ホスト
    Seccomp Notify
    2022/7/27

    View Slide

  15. Socket Switching の流れ
    bypass4netns では以下の手順に従い Socket Switching を行う
    ソケットに関係がある syscall をSeccomp Notify fd 経由でハンドル
    1. syscall の引数を読み出す
    2. syscall が接続先を指定している
    a. 接続先が外部のエンドポイント → Socket Switching を行う
    b. 接続先が外部のエンドポイントでない → 何もしない
    3. syscall がポートをバインドしている
    a. ポートが公開対象のポート → Socket Switching を行う
    b. ポートが公開対象のポートでない → 何もしない
    4. syscall がソケットの設定を行っている → 設定を記録
    SWoPP2022 7/27 OS-3 15
    slirp4netns
    を代替
    RootlessKit port driver
    を代替
    2022/7/27

    View Slide

  16. 既存アプリケーションにおけるソケット syscall の調査
    Socket Switching に必要な情報
    1. ソケットに関係する syscall
    2. 接続先/元が外部であると分かる syscall
    3. Socket Switching 前にソケットに対して実行される syscall
    トレーサーを用いてアプリケーションが利用する syscall を調査
    • socket(2) で作成された fd に対して実行される syscall を調査
    SWoPP2022 7/27 OS-3 16
    socket bind listen accept
    clone
    recv send
    accept accept
    PID=x
    PID=y
    fd=α fd=β
    2022/7/27

    View Slide

  17. 調査結果
    以下のアプリケーションを対象に調査
    • ping, wget, apache, nginx, iperf3
    • 対象となるソケットは SOCK_STREAM, SOCK_DGRAM
    • トレースのログを解析し、対象の syscall を抽出
    接続先/元が外部であると分かる syscall
    • connect, sendto(アドレス付き),bind
    Socket Switching 前にソケットに対して実行される syscall
    • ソケット作成後から接続先/元が外部であると分かるまでに実行される
    syscall を抽出
    • 設定を行うsyscall: setsockopt, ioctl
    SWoPP2022 7/27 OS-3 17
    2022/7/27

    View Slide

  18. bypass4netns での挙動
    Seccomp Notify で 以下の syscall をフック
    connect, sendto, bind, setsockopt, ioctl
    以下の手順で処理を行う
    1. Syscall の引数を読み出す
    2. Syscall が connect, sendto(アドレス付き)である
    a. 接続先が外部のエンドポイント → Socket Switching を行う
    b. 接続先が外部のエンドポイントでない → 何もしない
    3. Syscall が bind である
    a. ポートが公開対象のポート → Socket Switching を行う
    b. ポートが公開対象のポートでない → 何もしない
    4. Syscall が setsockopt, ioctl である → 引数を設定として記録
    SWoPP2022 7/27 OS-3 18
    2022/7/27

    View Slide

  19. bypass4netns での挙動
    Seccomp Notify を利用し接続先に応じて Socket Switching
    → コンテナ内のソケットと同じ設定のソケットをホスト上に作成する
    SWoPP2022 7/27 OS-3 19
    socket
    setsockopt
    connect
    socket
    setsockopt
    bypass4netns
    send
    ソケットの作成
    設定の反映
    Socket
    Switching
    設定を記録
    コンテナ ホスト
    Seccomp Notify
    2022/7/27

    View Slide

  20. 実装
    3つのコンポーネントを実装
    • bypass4netns: Seccomp Notify や Socket Switching の処理を担う
    • bypass4netnsd: nerdctl と連携し、bypass4netns の管理を担う
    • nerdctl(改修): bypass4netnsd との連携機能を追加
    実験的要素として nerdctl v0.17.0 にマージ済み
    ※nerdctl: 高レベルランタイムであるcontainerd用CLI. コンテナ関連の新機能の実験場として開発
    nerdctl run --label nerdctl/bypass4netns=true alpine で容易に利用可能
    SWoPP2022 7/27 OS-3 20
    2022/7/27

    View Slide

  21. 性能評価及び評価環境
    以下の観点で性能を評価
    • スループット
    • CPU使用率
    • syscall 実行のオーバーヘッド
    • アプリケーション(wget, nginx)
    評価には以下のHyper-V 上の VM 環境を利用
    • Host CPU: Ryzen 7 PRO 5850U
    • Host メモリ 32GB
    • Host OS: Windows 11 Pro (build 22000.739)
    • VM CPU: 4 コア
    • VM Memory: 8GB
    • VM OS: Ubuntu 21.10 (kernel 5.13.0-1025-azure)
    SWoPP2022 7/27 OS-3 21
    2022/7/27

    View Slide

  22. 性能評価(スループット)
    2つの場合についてスループットを iperf3 で計測
    Case A. コンテナと接続先/元ホストが同一VM
    Case B. コンテナと接続先/元ホストが別のVM
    → いずれの場合についても、従来より性能が向上したことを確認
    38.6 39.2
    0.452
    35.8
    41.4 39.8
    0
    10
    20
    30
    40
    50
    Container → Host Host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    16.8 16.0
    1.11
    13.6
    21.0
    16.1
    0
    5
    10
    15
    20
    25
    Container → Other host Other host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    2022/7/27 22
    A. コンテナと接続先/元ホストが同一VM B. コンテナと接続先/元ホストが別のVM

    View Slide

  23. 性能評価(CPU使用率)
    iperf3(1Gbps制限,120秒間)動作中のCPU使用率(sys + user)を計測
    → いずれの場合でも、従来よりCPU使用率が減少したことを確認
    23
    2022/7/27
    0
    5
    10
    15
    20
    25
    30
    35
    40
    0
    3
    6
    9
    12
    15
    18
    21
    24
    27
    30
    33
    36
    39
    42
    45
    48
    51
    54
    57
    60
    63
    66
    69
    72
    75
    78
    81
    84
    87
    90
    93
    96
    99
    102
    105
    108
    111
    114
    117
    120
    CPU使用率(user + sys) %
    経過時間(秒)
    w/ bypass4netns(case A) w/o bypass4netns(case A) w/ bypass4netns(case B) w/o bypass4netns(case B)

    View Slide

  24. 性能評価(syscall 実行のオーバーヘッド)
    単純なプログラムで syscall 実行のオーバーヘッドを計測
    • socket(SOCK_DGRAM), connect, close を繰り返す
    • 10万回実行し、平均値で比較
    →従来より実行に30倍の時間を要することを確認
    Seccomp Notify では特定の syscall のみ処理するため、
    実アプリケーションならば影響は小さくなると考えられる
    SWoPP2022 7/27 OS-3 24
    w/o bypass4netns w/bypass4netns
    1回あたりの実行時間(us) 3.22 100.05
    2022/7/27

    View Slide

  25. 性能評価(wget)
    コンテナ内で外部へ wget を実行したときにかかる時間を計測
    • 環境は B. 別VM で、Nginx をサーバーとして利用
    → 小さいファイルは Socket Switching のオーバーヘッドの影響が出ている
    ファイルサイズが一定以上でRootfulな場合と同等の性能
    SWoPP2022 7/27 OS-3 25
    0
    1
    2
    3
    4
    5
    6
    1KiB 32KiB 128KiB 512KiB 1MiB
    ダウンロード時間(ミリ秒)
    ファイルサイズ
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    0
    0.5
    1
    1.5
    2
    2.5
    32MiB 128MiB 512MiB 1GiB
    ダウンロード時間(秒)
    ファイルサイズ
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    2022/7/27

    View Slide

  26. 性能評価(nginx)
    コンテナ内の nginx を公開した場合でダウンロード時間を計測
    • 環境は B. 別VM で、wget をクライアントとして利用
    → bypass4netns を用いない場合に比べて用いる場合のほうが高速
    Rootful なコンテナとほぼ同等の性能
    SWoPP2022 7/27 OS-3 26
    0
    1
    2
    3
    4
    5
    6
    1KiB 32KiB 128KiB 512KiB 1MiB
    ダウンロード時間(ミリ秒)
    ファイルサイズ
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    0
    0.05
    0.1
    0.15
    0.2
    0.25
    0.3
    0.35
    0.4
    0.45
    32MiB 128MiB 512MiB 1GiB
    ダウンロード時間(秒)
    ファイルサイズ
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    2022/7/27

    View Slide

  27. 考察
    1. 他のネットワークコンポーネントとの組み合わせ
    コンテナのNetNSや内部NetNSをバイパスすることによる弊害
    • 外部エンドポイントへの通信の制御をホスト側でする必要がある(要特権)
    2. セキュリティ
    • NetNSによるネットワークの分離を壊している
    • Seccomp Notify で time-of-check to time-of-use(TOCTOU)攻撃が
    成立する可能性がある
    3. slirp4netns, RootlessKit との関係(bypass4netns の制約)
    • VXLAN をサポートしない→ Usernetes 等では利用できない
    ※ Usernetes: 特権なしで動く Kubernetes
    • 全ての通信について bypass4netns で高速化できるわけではない
    SWoPP2022 7/27 OS-3 27
    2022/7/27

    View Slide

  28. まとめ
    目的: Rootless Container における外部へ/からの通信の高速化
    • Rootless 化による通信性能の劣化の改善
    提案: Socket Switching による高速化手法 bypass4netns
    • コンテナ内のソケットをホスト上のソケットに差し替える
    実装, 評価: 既存のモジュールに比べて高速化を達成
    • コンテナ内→外部の通信については 約20倍の高速化を達成
    考察: セキュリティ上の課題や bypass4netns 自体の制約が存在
    • 従来のネットワークモジュールと組み合わせた利用が必要
    SWoPP2022 7/27 OS-3 28
    2022/7/27

    View Slide

  29. 補足資料: 性能評価(スループット)
    -r オプション(server → client に流す)場合についても同様の傾向
    SWoPP2022 7/27 OS-3 29
    53.5
    43.0
    4.25
    26.1
    55.2
    45.2
    0
    10
    20
    30
    40
    50
    60
    Container → Host Host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    13.5
    20.9
    3.56
    11.8
    13.6
    21.2
    0
    5
    10
    15
    20
    25
    Container → Host Host → Container
    Throughput(Gbps)
    Rootful Rootless w/o bypass4netns Rootless w/ bypass4netns
    A. コンテナと接続先/元ホストが同一VM B. コンテナと接続先/元ホストが別のVM
    2022/7/27

    View Slide

  30. 補足資料: 性能評価(スループット)
    bypass4netns を使うとRootful なコンテナより速い場合がある
    → iptables や veth, bridge のオーバーヘッドによる可能性
    curl のパケット処理に関係したカーネル関数数を ipftrace2 で集計
    Rootful な場合に比べて、bypass4netns の場合は関数数が少ないことを確認
    → bypass4netns を利用する場合が速い原因の一つとして考えられる
    SWoPP2022 7/27 OS-3 30
    Rootful w/o bypass4netns w/ bypass4netns
    処理カーネル関数数 673 922 198
    2022/7/27

    View Slide

  31. 補足資料: トレース結果(wget)
    • DNS 名前解決 → 仮接続 → TCP 接続で取得
    • connect(2) で差し替えた直後に ioctl(2) や fnctl(2) を実行
    • ハンドルする必要は特にない
    • connect(2) 前に実行される場合はありそう?
    31
    2022/7/27

    View Slide

  32. 補足資料: トレース結果(Nginx)
    • Nginx 特有のイベント多重な処理が行われていることが分かる
    • 複数プロセスでの epoll_wait による待ち受け
    • bind(2) → listen(2) → 別プロセスで accept(2)
    • bind(2) 以降は特にハンドルする必要はない
    32
    2022/7/27 SWoPP2022 7/27 OS-3

    View Slide