XDP入門

こんにちは.閃光のハサウェイが配信開始されたので早速視聴しました.メッサーがいいですね.

前回もXDP関連の話題でしたが,今回はXDPに入門します. XDPを学習する際のロードマップやつまりどころの解消になればと思います.

2023-12-30 加筆

本記事を公開して約 2 年が経過しました. この加筆で古くなってしまった情報を修正しています. 差分は このブログの Github の PR を見てください.

この 2 年間で eBPF 及び XDP への注目はさらに高まったように感じます. 取得できる情報も充実してきました. 特に O’reilly より発売された 入門 eBPF(原書: Learning eBPF) は非常に充実した内容になっています. 日本語でこれらの情報に触れられるようになったことは大変ありがたいです.

2023 年は個人的にも XDP に関して新たに発展的なコンテンツを作成しました.

そちらも触っていただければと思います.

[Read More]

Goのcilium/ebpfでXdpcapを使う

こんにちは.学生生活も後少しとなってしまいました.悲しいです. 今回はxdpcapというツールについてです.xdpcapの使用に関する資料が日本語では非常に少なかったので使い方を紹介します.

[Read More]

KLab Expert Camp TCP/IPプロトコルスタック自作開発キャンプに参加してきました.

こんにちは.趣味の将棋がなかなか強くならなくて困ってます.勉強せずにすぐ対局してしまうのがダメなのはわかってますがつい対局してしまいます. 今回はKLab Expert Campに参加してTCP/IPプロトコルスタック自作に挑戦しました.

[Read More]

SoftEther VPN Server APIのGo版を作った

こんにちは.最近は学校の課題や事務手続きやらインターンどうしようかやらで非常に忙しいです.それに加えてSecHack365に参加することとなりこれはうれしい悲鳴ですがさらに忙しいです.(嬉しい) さて今回はSoftEtherについてです.学生などにはあまり馴染みがなさげなソフトですが,僕は研究でこのソフトに非常にお世話になっております.このソフトウェアはとてもすごいんですが,マネージャーソフトがwindows用しかなくてCUIベースの操作が大変なのでWebベースのマネージャーを作ろうと思い立ちました.そこでまずGo言語でAPIのラッパーを作成しました.

[Read More]

自作コンテナランタイムでつまずいてる話

こんにちは.緊急事態宣言がのびたので相変わらずの外出自粛中です.最近は外出自粛にも少し慣れましたがやはり退屈です.僕は作業中のBGMとして何度か見たことのあるアニメなどを流しているんですがそれらのストックも無くなってきています.ループしようかな.ちなみにおすすめはガンダムUCですね.音楽が素晴らしいですし,SFアニメはモチベが上がっていいです. さて,今回は自作コンテナランタイムに挑戦したという話です.前回のポストではruncを使ってみましたが,今回はruncを参考に挑戦してみました.

ちなみにコード書いて試してたときにrm -rfで書いてたコード全消去して萎えました.

gitで管理するのって大事ですね. リポジトリはこちら

タイトルについて

タイトルにつまずいているとつけましたが,つまずいてます.長い間同じ箇所でエラーがでて前に進めていません. 僕の魂の叫びがこちら.

[Read More]

runcを使ってみる

こんにちは.前回のポストからだいぶ時間が空きましたが,相変わらず緊急事態宣言中で自宅待機なので時間を持て余しています. ONE PIECEを読み返していたんですが,無料で読める分を読み終わってしまったので暇です. 今回はdockerに使用されているコンテナランタイムであるruncを使ってみました. では,いきます.

[Read More]

セキュアなコンテナgVisor

こんにちは.緊急事態宣言が出ているため相変わらず外出ができません.早く収束して欲しいものです. 今回はdocker関連の話題についてです.Googleが開発したgVisorというコンテナランタイムについて調べてみました.

gVisor

Documentを意訳

gVisorとはGo言語で実装されたユーザー空間カーネルです.ほとんどのLinuxシステムコールインターフェースを実装しており,ホストOSと起動しているアプリケーションとの間に隔離層を設けることで安全性を実現しています. gVisorにはrunscというOCI仕様に準拠したコンテナランタイムを含んでいます.runscはDockerやKubernetesで使用でき,簡単にサンドボックス化されたコンテナを実行できます. gVisorは既存のサンドボックス化ツールと異なるアプローチを用いています.

[Read More]

ネットワークを作って理解しようとする(ARP編)

こんにちは. 新型コロナの影響で外出を控えているのですが,ずっと自宅にいるのも結構しんどいですね. この前見始めた鬼滅の刃ももう見終わってしまいました.続きが気になります. さて,今回もネットワークシリーズです.

ネットワークを作って理解する

ネットワークの仕組みを理解するためには作ってみるのが一番ということでプロトコルスタックを自作してみます. 前回はEthernetを実装してみました.前回のポストはこちら 今回はデータリンク層のアドレスとネットワーク層のアドレスを解決するARPを実装してみたいと思います.使用言語はgolangです.

[Read More]

ネットワークを作って理解しようとする(Ethernet編)

こんにちは. 今週末は新型コロナの影響で外出自粛なので暇を持て余しております. 暇なのでNetflixで鬼滅の刃を見始めました.面白いですね〜.

ネットワークを作って理解する

最近の興味としてネットワークの仕組みを理解したいというのがあり,プロトコルスタック自作なるものを知りました.とはいえ僕はC言語が得意でないのでGo言語で作ってみようと思い作成を始めました.というわけて何回かに分けて紹介したいと思います.

OSI参照モデル

OSI参照モデルとはコンピュータの通信機能を階層構造に分割したモデルです. 各階層にはそれぞれが担うべき機能が定義されています. データリンク層では隣接するノード間のデータの通信をサポートします. osi-model

開発環境

開発環境は以下の通りです.ioctlなどのシステムコールを扱うためprivilegeオプションを有効にしたLinuxコンテナを作成してプログラムをビルドします. また,実行はコンテナの中でネットワーク名前空間を分離して行います.

  • Mac OS Catalina
  • VSCode
  • Docker version 19.03.5, build 633a0ea

実装

リポジトリはこちら

物理層からデータを受け取る

今回のプログラムでは生のパケットを受け取る必要があります.golangの標準パッケージでは生のパケットを扱うことができないため別の方法で生のパケットを取得しなければいけません.そこで今回のプログラムでは以下の二つの方法で生のパケットを取得します.

  • PF_PACKET
  • Tun/Tapデバイス

PF_PACKET

PF_PACKETはLinuxのsocketシステムコールで生のパケットを扱うためのドメインです.syscallパッケージのSocket関数を用いて以下のようにソケットを開きます.

protocol := hton16(syscall.ETH_P_ALL)
fd, err := syscall.Socket(syscall.AF_PACKET, syscall.SOCK_RAW, int(protocol))
if err != nil {
    return -1, err
}

開いたソケットを用いてPFPacket構造体を定義します.

type PFPacket struct {
	fd                 int
	name               string
	address            ethernet.HardwareAddress
	netInfo            ip.IPSubnetMask
	registeredProtocol []LinkNetProtocol
	MTU                int
	buffer             chan *ethernet.EthernetFrame
}

Tun/Tap

Tun/TapはUnixで使用できる仮想ネットワークデバイスです.Tun/Tapデバイスに届いたパケットは直接ユーザープログラムに送られます. Tun/Tapデバイスは以下のように開きます.

const device = "/dev/net/tun"

file, err := os.OpenFile(device, os.O_RDWR, 0600)
	if err != nil {
		return "", nil, err
	}

開いたファイルを用いてTun構造体を定義します.

type Tun struct {
	file               io.ReadWriteCloser
	name               string
	address            ethernet.HardwareAddress
	netInfo            ip.IPSubnetMask
	registeredProtocol []LinkNetProtocol
	MTU                int
	buffer             chan *ethernet.EthernetFrame
}

Deviceインターフェース

DeviceインターフェースでPF_PACKETとTunデバイスの差を吸収します.

[Read More]