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

権威DNSサービスへのDDoSと
ハイパフォーマンスなベンチマーカ / DNS Pseudo random subdomain attack and High performance Benchmarker

kazeburo
March 19, 2023

権威DNSサービスへのDDoSと
ハイパフォーマンスなベンチマーカ / DNS Pseudo random subdomain attack and High performance Benchmarker

権威DNSサービスへのDDoSと
ハイパフォーマンスなベンチマーカ
YAPC::Kyoto 2023 at Kyoto Research Park 2023/03/19

kazeburo

March 19, 2023
Tweet

More Decks by kazeburo

Other Decks in Technology

Transcript

  1. 権威DNSサービスへのDDoSと

    ハイパフォーマンスなベンチマーカ
    YAPC::Kyoto 2023 at Kyoto Research Park 2023/03/19
    さくらインターネット株式会社 クラウド事業本部 SRE室 Masahiro Nagano (kazeburo)

    View Slide

  2. Me
    • ⻑野雅広(ながのまさひろ)
    • CPAN: KAZEBURO
    • Twitter/GitHub @kazeburo
    • 2006年まで京都リサーチパーク4号館で勤務
    • さくらインターネット株式会社 クラウド事業本部

    SRE室 室⻑
    • ISUCON1, 2, 9予選出題。ISUCON3, 4優勝

    View Slide

  3. さくらインターネット SRE室の取り組み
    • ミッション
    • クラウドサービスの信頼性を⾼めることにより、お客様や社会のDXをしっかり⽀える
    • ビジョン
    • 社内でのSREの実践を広め、お客様への価値提供を⾏う
    • さくらのサービスそのものの信頼性向上、それにより価値向上を⽬指す
    • さくら社員がEnabling SREとして、お客様・社外のサービスの信頼性向上に携わる

    View Slide

  4. さくらインターネット SRE室の取り組み
    • SRE as a Service
    • 社内における Kubernetes 基盤構築
    • ログ/監視基盤の研究開発
    • Embedded SRE / Enabling SREとしての取り組み 
    • クラウドサービスのチーム開発/運⽤体制作り
    • CI/CDなどDX(Develoer Experience)向上の仕組みの構築
    • 既存クラウドサービスの開発運⽤

    View Slide

  5. DNS⽔責め攻撃
    ランダムサブドメイン

    View Slide

  6. 「DNS⽔責め攻撃」とは
    • 攻撃対象に⼤量のランダムなサブドメイン(foo-bar-baz.example.com)を問
    い合わせてDNSの機能停⽌、機能低下を狙う攻撃
    • 攻撃者はオープンリゾルバ(DNSキャッシュサーバ)に対して、⼤量のラン
    ダムサブドメインの問い合わせを発⽣させる
    • DNSキャッシュサーバにはキャッシュがなく、権威DNSサーバに⼤量の問
    い合わせが発⽣し、DDoSとなる

    View Slide

  7. 「DNS⽔責め攻撃」とは
    • ランダムサブドメイン攻撃 (Pseudo-Random Subdomain Attack) と呼ばれ
    ることも
    • 2014年に初めて観測 (https://cybersecurity-jp.com/column/34745)
    • DNSによる名前解決として正しい動作、通信パケットであり防ぐのが難しい
    • GoogleやCloud
    fl
    areのPublic DNSが利⽤されるため、単純なブロックがで
    きない

    View Slide

  8. 実際の攻撃の記録(1分間あたりのクエリ数)
    12/15から12/16まで1⽇近く、900万クエリ/分(15万qps)の攻撃が続いた

    View Slide

  9. 実際の攻撃(tcpdump)
    07:25:11.719035 IP 209.216.160.2.50051 > 133.242.64.100.53: 43104 A? meetmodeling.example.com. (50)


    07:25:11.719057 IP 205.171.30.238.44916 > 133.242.64.100.53: 64321% [1au] A? _.modeling.example.com. (71)


    07:25:11.719069 IP 172.70.109.31.63292 > 133.242.64.100.53: 40380 [1au] A? osaExpe1-pLatINUM.exAmpLe.cOm. (66)


    07:25:11.719071 IP 3.139.136.204.44597 > 133.242.64.100.53: 32383% [1au] A? webdirect.foster.example.com. (65)


    07:25:11.719113 IP 18.188.77.103.42513 > 133.242.64.100.53: 14853 [1au] A? note-modeling.example.com. (62)


    07:25:11.719132 IP 172.70.33.19.27971 > 133.242.64.100.53: 35379 [1au] A? indian-awarded.example.com. (63)


    07:25:11.719147 IP 12.121.89.48.43564 > 133.242.64.100.53: 23891 A? matchfiling.example.com. (49)


    07:25:11.719156 IP 74.125.181.130.64517 > 133.242.64.100.53: 25285% [1au] A? xmL.mODeLING.eXaMple.CoM. (61)


    07:25:11.719166 IP 165.225.41.202.17203 > 133.242.64.100.53: 53044% [1au] A? qatawarded.example.com. (59)


    07:25:11.719176 IP 96.114.53.67.20082 > 133.242.64.100.53: 41999 [1au] A? netherlands.filing.example.com. (67)


    07:25:11.719190 IP 172.253.195.196.35276 > 133.242.64.100.53: 45639% [1au] A? tdd-modeling.example.com. (61)


    07:25:11.719195 IP 172.253.217.12.40587 > 133.242.64.100.53: 62658% [1au] A? web.modeling.example.com. (61)


    07:25:11.719197 IP 172.253.9.4.50295 > 133.242.64.100.53: 37961% [1au] A? co.awarded.example.com. (59)


    07:25:11.719224 IP 172.71.29.39.30489 > 133.242.64.100.53: 2496 [1au] A? SfaaSobvioUs.ExamplE.Com. (61)


    07:25:11.719235 IP 209.66.107.33.57264 > 133.242.64.100.53: 50511 [1au] A? hap.modeling.example.com. (61)


    07:25:11.719275 IP 96.114.53.69.53157 > 133.242.64.100.53: 5679 [1au] A? gitcn-awarded.example.com. (62)


    07:25:11.719312 IP 172.70.229.30.59530 > 133.242.64.100.53: 45890 [1au] A? ipafoster.example.com. (58)


    07:25:11.719336 IP 172.217.46.78.59507 > 133.242.64.100.53: 60186% [1au] A? testcloud-modeling.example.com. (67)


    07:25:11.719351 IP 69.47.193.166.52891 > 133.242.64.100.53: 238 [1au] A? bfmpassing.example.com. (59)


    07:25:11.719353 IP 34.218.119.91.26001 > 133.242.64.100.53: 31511% [1au] A? signal-modeling.example.com. (64)


    07:25:11.719365 IP 34.218.119.91.13381 > 133.242.64.100.53: 4210% [1au] A? pairfiling.example.com. (59)

    View Slide

  10. 実際の攻撃(tcpdump)
    07:25:11.719035 IP 209.216.160.2.50051 > 133.242.64.100.53: 43104 A? meetmodeling.example.com. (50)


    07:25:11.719057 IP 205.171.30.238.44916 > 133.242.64.100.53: 64321% [1au] A? _.modeling.example.com. (71)


    07:25:11.719069 IP 172.70.109.31.63292 > 133.242.64.100.53: 40380 [1au] A? osaExpe1-pLatINUM.exAmpLe.cOm. (66)


    07:25:11.719071 IP 3.139.136.204.44597 > 133.242.64.100.53: 32383% [1au] A? webdirect.foster.example.com. (65)


    07:25:11.719113 IP 18.188.77.103.42513 > 133.242.64.100.53: 14853 [1au] A? note-modeling.example.com. (62)


    07:25:11.719132 IP 172.70.33.19.27971 > 133.242.64.100.53: 35379 [1au] A? indian-awarded.example.com. (63)


    07:25:11.719147 IP 12.121.89.48.43564 > 133.242.64.100.53: 23891 A? matchfiling.example.com. (49)


    07:25:11.719156 IP 74.125.181.130.64517 > 133.242.64.100.53: 25285% [1au] A? xmL.mODeLING.eXaMple.CoM. (61)


    07:25:11.719166 IP 165.225.41.202.17203 > 133.242.64.100.53: 53044% [1au] A? qatawarded.example.com. (59)


    07:25:11.719176 IP 96.114.53.67.20082 > 133.242.64.100.53: 41999 [1au] A? netherlands.filing.example.com. (67)


    07:25:11.719190 IP 172.253.195.196.35276 > 133.242.64.100.53: 45639% [1au] A? tdd-modeling.example.com. (61)


    07:25:11.719195 IP 172.253.217.12.40587 > 133.242.64.100.53: 62658% [1au] A? web.modeling.example.com. (61)


    07:25:11.719197 IP 172.253.9.4.50295 > 133.242.64.100.53: 37961% [1au] A? co.awarded.example.com. (59)


    07:25:11.719224 IP 172.71.29.39.30489 > 133.242.64.100.53: 2496 [1au] A? SfaaSobvioUs.ExamplE.Com. (61)


    07:25:11.719235 IP 209.66.107.33.57264 > 133.242.64.100.53: 50511 [1au] A? hap.modeling.example.com. (61)


    07:25:11.719275 IP 96.114.53.69.53157 > 133.242.64.100.53: 5679 [1au] A? gitcn-awarded.example.com. (62)


    07:25:11.719312 IP 172.70.229.30.59530 > 133.242.64.100.53: 45890 [1au] A? ipafoster.example.com. (58)


    07:25:11.719336 IP 172.217.46.78.59507 > 133.242.64.100.53: 60186% [1au] A? testcloud-modeling.example.com. (67)


    07:25:11.719351 IP 69.47.193.166.52891 > 133.242.64.100.53: 238 [1au] A? bfmpassing.example.com. (59)


    07:25:11.719353 IP 34.218.119.91.26001 > 133.242.64.100.53: 31511% [1au] A? signal-modeling.example.com. (64)


    07:25:11.719365 IP 34.218.119.91.13381 > 133.242.64.100.53: 4210% [1au] A? pairfiling.example.com. (59)
    • ランダムな⽂字列、単語の組み合わせ
    • ⼤⽂字・⼩⽂字まざり(Google Public DNS仕様)
    • ラベル数が増えることも

    View Slide

  11. なぜ「⽔責め攻撃」が有効か
    • キャッシュに存在しない⼤量のクエリ
    • DNSサーバ側でのDNSリクエストのパケット処理が必要となる
    • さくらのクラウド DNSアプライアンスではお客様のDNSレコードを管理し
    やすくするため PowerDNSおよびRDBMS(MySQL/MariaDB) をDNSサー
    バのバックエンドとして利⽤
    • DNSサーバが持つキャッシュにヒットしないため都度SQLが発⾏
    • CPU負荷によりサービスに影響

    View Slide

  12. 「⽔責め攻撃」への対策
    • 存在するレコードへのクエリ以外はDNSサーバの⼿前でフィルタする
    • dnsdist(https://dnsdist.org/) というDNSのProxyサーバを導⼊ ✅
    • 新たなドメインに対する⽔責め攻撃の対策にはならず
    • 攻撃を受け切るパフォーマンス💪
    • スケールアウト/スケールアップ/負荷分散/チューニング
    • RDBMS を使うバックエンドをやめる🌸

    View Slide

  13. View Slide

  14. View Slide

  15. DNS⽔責め攻撃に対する
    DNSサーバのパフォーマンスを測る

    View Slide

  16. (権威)DNSサーバのベンチマークツール
    • dnsperf
    • https://github.com/DNS-OARC/dnsperf
    • あらかじめ問い合わせするクエリをファイルに記述しベンチマークを⾏う
    • ⾃作する
    • ランダム⽂字列の⼤⽂字⼩⽂字、⻑さや数を柔軟に変更したい
    • ベンチマーカから対象まで全体を把握できる。DNSについて学べる

    View Slide

  17. 作りました

    View Slide

  18. 3/10に実⾏

    View Slide

  19. package main


    import (


    "fmt"


    "math/rand"


    "net"


    "time"


    )


    const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"


    func randString(n int) string {


    rand.Seed(time.Now().UnixNano())


    b := make([]byte, n)


    for i := range b {


    b[i] = letterBytes[rand.Intn(len(letterBytes))]


    }


    return string(b)


    }


    func main() {


    for i := 0; i < 1000; i++ {


    randStr := randString(10) // 10จࣈͷϥϯμϜจࣈྻΛੜ੒


    addrs, err := net.LookupHost(randStr)


    if err != nil {


    fmt.Printf("Failed to resolve %s: %v\n", randStr, err)


    } else {


    fmt.Printf("%s resolves to %v\n", randStr, addrs)


    }


    }


    } 3/10に実⾏

    View Slide

  20. package main


    import (


    "fmt"


    "math/rand"


    "net"


    "time"


    )


    const letterBytes = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"


    func randString(n int) string {


    rand.Seed(time.Now().UnixNano())


    b := make([]byte, n)


    for i := range b {


    b[i] = letterBytes[rand.Intn(len(letterBytes))]


    }


    return string(b)


    }


    func main() {


    for i := 0; i < 1000; i++ {


    randStr := randString(10) // 10จࣈͷϥϯμϜจࣈྻΛੜ੒


    addrs, err := net.LookupHost(randStr)


    if err != nil {


    fmt.Printf("Failed to resolve %s: %v\n", randStr, err)


    } else {


    fmt.Printf("%s resolves to %v\n", randStr, addrs)


    }


    }


    }
    ちゃんと動きそう..?

    View Slide

  21. コードの問題点を中の⼈に確認してみた
    • このコードを利⽤してDNSサーバの性能評価を⾏う場合、以下の問題点が考えられます。
    1. このコードは、⼀つのプログラムから直列でDNSリクエストを送信するため、実際のユ
    ーザーからのリクエストとは異なる負荷がかかる可能性があります。実際のユーザーか
    らのリクエストは、同時に多数のリクエストが発⽣することがありますが、このコード
    では⼀つずつリクエストが発⽣するため、DNSサーバの性能評価としては適切ではあり
    ません。
    2.このコードは、名前解決の際にエラーが発⽣した場合に、そのエラーを表⽰するだけで
    処理を続⾏します。しかし、実際のユーザーからのリクエストでは、エラーが発⽣した
    場合には適切にエラー処理を⾏う必要があります。
    3/16に実⾏(⼀部抜粋)

    View Slide

  22. ベンチマーカの必要条件
    • 多数のリクエストを⾏うパフォーマンス 💪
    • 適切なエラーが取得可能であること🔍

    View Slide

  23. 適切なエラー処理
    • どこでエラーが起きたのか明らかにする
    • ベンチマークはテストでもある
    • 意図した失敗を許容できる
    • DNSで起きるエラー
    • Timeout (Drop含む)
    • NXDOMAIN: ドメインが⾒つからない
    • SERVFAIL: エラーの発⽣
    • REFUSED: 拒否

    View Slide

  24. エラー処理(net.Resolver)
    func do() {


    r := &net.Resolver{


    PreferGo: true,


    Dial: func(ctx context.Context, network, address string) (net.Conn, error) {


    d := net.Dialer{


    Timeout: timeout,


    }


    return d.DialContext(ctx, protocol, net.JoinHostPort(host, port))


    },


    }


    sub := randString(10)


    _, err := r.LookupHost(context.Background(), sub+"."+zone)


    if err := err.(*net.DNSError); err.IsNotFound {


    }


    }
    エラーは取得できるが、詳しい内容はエラーの⽂⾔を解析しないとわからない
    (LookupHostはAと同時にAAAAの名前解決を⾏う)

    View Slide

  25. エラー処理(miekg/dnsの)
    import "github.com/miekg/dns"


    atype = dns.StringToType["A"]


    func do() {


    c := &dns.Client{Net: protocol, Timeout: timeout}


    address := net.JoinHostPort(host, port)


    m := new(dns.Msg)


    sub := randString(10)


    m.SetQuestion(sub+”.”+zone+”.", atype)


    r, _, err := c.Exchange(m, address)


    if err != nil {


    }


    if r.Rcode == dns.RcodeRefused {


    }


    }
    Pure GoなシンプルなAPIとコード
    DNSのステータス(RCODE)が取得可能

    View Slide

  26. パフォーマンス💪
    • 対象のパフォーマンス > ベンチマーカのパフォーマンスでは正しい計測ができない
    • 現代において Apache Bench が常に適切なツールとはならない
    • クライアント側にもハイパフォーマンスが求められる
    • ベンチマークにとって余分な処理の削減(Happy EyeBallsなど)
    • 並⾏・並列化
    • パフォーマンスチューニング

    View Slide

  27. 並⾏・並列化
    Use Goroutines
    ctx, cancel := context.WithTimeout(


    context.Background(),


    timeLimit,


    )


    defer cancel()


    for w := 0; w < maxWorkers; w++ {


    go func() {


    for {


    do()


    }


    }()


    }


    <- ctx.Done()
    import "github.com/miekg/dns"


    atype = dns.StringToType["A"]


    func do() {


    c := &dns.Client{Net: protocol, Timeout: timeout}


    address := net.JoinHostPort(host, port)


    m := new(dns.Msg)


    sub := randString(10)


    m.SetQuestion(sub+”.”+zone+”.", atype)


    r, _, err := c.Exchange(m, address)


    if err != nil {


    }


    if r.Rcode == dns.RcodeRefused {


    }


    }
    goroutineを起動し、
    名前解決をループで実⾏

    View Slide

  28. Goのパフォーマンスチューニング
    • メモリーアロケーションしない
    • 計測をしましょう
    • 最後のGOGC

    View Slide

  29. メモリーアロケーションを減らす
    import "github.com/miekg/dns"


    ctx, cancel := context.WithTimeout(


    context.Background(),


    timeLimit,


    )


    defer cancel()


    for w := 0; w < maxWorkers; w++ {


    go func() {


    c := &dns.Client{Net: protocol,


    Timeout: timeout}


    m := new(dns.Msg)


    address := net.JoinHostPort(host, port)


    for {


    do(c, m, address)


    }


    }()


    }


    <- ctx.Done()
    var atype = dns.StringToType[“A"]


    func do(c *dns.Client,


    m *dns.Msg,


    address string


    ) {


    sub := randString(10)


    m.SetQuestion(sub+”.”+zone+”.", atype)


    r, _, err := c.Exchange(m, address)


    if err != nil {


    }


    if r.Rcode == dns.RcodeRefused {


    }


    }
    ループごとに初期化する
    必要ない。ループの外へ移動する

    View Slide

  30. ⽂字列連結の⾼速化
    • Go⾔語では⽂字列はImmutable
    • ⽂字列の連結は新しい⽂字列をアロケーションする
    zone := randString(10)


    zone += “.”


    zone += “example.com"


    zone += “.”


    m.SetQuestion(zone, atype)

    View Slide

  31. ⽂字列連結の⾼速化
    バッファの再利⽤
    import (


    “strings"


    “github.com/miekg/dns"


    )


    for w := 0; w < maxWorkers; w++ {


    go func() {


    c := &dns.Client{Net: protocol,


    Timeout: timeout}


    m := new(dns.Msg)


    address := net.JoinHostPort(host, port)


    bb := new(bytes.Buffer)


    for {


    do(c, m, address, bb)


    }


    }()


    }


    <- ctx.Done()
    var atype = dns.StringToType[“A"]


    func do(c *dns.Client,


    m *dns.Msg,


    address string


    bb *bytes.Buffer


    ) {


    defer sb.Reset()


    randString(bb, 10)


    bb.WriteByte('.')


    bb.WriteString(opt.Zone)


    bb.WriteByte('.')


    b := sb.Byte()


    z := unsafe.String(&b[0], len(b))


    m.SetQuestion(z, atype)


    r, _, err := c.Exchange(m, address)


    }
    ループの外でbufferを作成し
    ループの中でresetして使い回す

    View Slide

  32. ランダム⽂字列の⽣成
    // https://stackoverflow.com/questions/22892120/how-to-generate-a-random-string-of-a-fixed-length-in-go


    const (


    letterBytes = "abcdefghijklmnopqrstuvwxyz0123456789"


    letterIdxBits = 6 // 6 bits to represent a letter index


    letterIdxMask = 1<

    letterIdxMax = 63 / letterIdxBits // # of letter indices fitting in 63 bits


    )


    func randString(bb *bytes.Buffer, n int) {


    for i, cache, remain := n-1, int63(), letterIdxMax; i >= 0; {


    if remain == 0 {


    cache, remain = int63(), letterIdxMax


    }


    if idx := int(cache & letterIdxMask); idx < len(letterBytes) {


    bb.WriteByte(letterBytes[idx])


    i--


    }


    cache >>= letterIdxBits


    remain--


    }


    }
    新たな⽂字列を⽣成することなく
    ランダムな⽂字を追記していく

    View Slide

  33. チューニングの結果の計測
    % go test -bench . -benchmem -benchtime 3s


    goos: darwin


    goarch: amd64


    pkg: github.com/kazeburo/bench


    cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz


    BenchmarkDo-8 2798367 1269 ns/op 28 B/op 3 allocs/op


    BenchmarkDoMoto-8 324367 10319 ns/op 224 B/op 8 allocs/op


    PASS


    ok github.com/kazeburo/bench 8.465s
    9倍程度⾼速化
    (dns.SetQuestionまで)
    1回あたりのアロケー
    ション回数(allocs/
    op)
    1回あたりのアロ
    ケーションで確保
    した容量(B/op)
    実⾏した回数 1回あたりの実⾏に掛か
    った時間(ns/op)

    View Slide

  34. チューニングの結果の計測
    % go test -bench . -benchmem -benchtime 3s


    goos: darwin


    goarch: amd64


    pkg: github.com/kazeburo/bench


    cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz


    BenchmarkDo-8 2798367 1269 ns/op 28 B/op 3 allocs/op


    BenchmarkDoMoto-8 324367 10319 ns/op 224 B/op 8 allocs/op


    PASS


    ok github.com/kazeburo/bench 8.465s
    9倍程度⾼速化
    (dns.SetQuestionまで)
    1回あたりのアロケー
    ション回数(allocs/
    op)
    1回あたりのアロ
    ケーションで確保
    した容量(B/op)
    実⾏した回数 1回あたりの実⾏に掛か
    った時間(ns/op)

    View Slide

  35. プロファイリングを⾏う
    go test -cpuprofile cpu.prof -memprofile mem.prof -benchtime 3s -bench 'BenchmarkDo$'


    goos: darwin


    goarch: amd64


    pkg: github.com/kazeburo/bench


    cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz


    BenchmarkDo-8 2401633 1478 ns/op


    PASS


    ok github.com/kazeburo/bench 5.362s

    View Slide

  36. プロファイリング
    % go tool pprof -top mem.prof


    Type: alloc_space


    Time: Mar 13, 2023 at 4:08pm (JST)


    Showing nodes accounting for 99.73MB, 100% of 99.73MB total


    flat flat% sum% cum cum%


    87MB 87.24% 87.24% 98MB 98.27% github.com/miekg/dns.(*Msg).SetQuestion


    10.50MB 10.53% 97.77% 11MB 11.03% github.com/miekg/dns.id


    1.16MB 1.16% 98.93% 1.16MB 1.16% runtime/pprof.StartCPUProfile


    0.57MB 0.57% 99.50% 0.57MB 0.57% compress/flate.newDeflateFast (inline)


    0.50MB 0.5% 100% 0.50MB 0.5% encoding/binary.Read


    0 0% 100% 0.57MB 0.57% compress/flate.(*compressor).init


    0 0% 100% 0.57MB 0.57% compress/flate.NewWriter


    0 0% 100% 0.57MB 0.57% compress/gzip.(*Writer).Write


    0 0% 100% 98MB 98.27% github.com/kazeburo/bench.BenchmarkDo


    0 0% 100% 98MB 98.27% github.com/kazeburo/bench.do


    0 0% 100% 1.16MB 1.16% main.main


    0 0% 100% 1.16MB 1.16% runtime.main



    このあたりがアヤシイ

    View Slide

  37. dns.SetQuestion Hack
    • 問い合わせを格納している配列を都度⽣成している
    • 配列を使い回し、問い合わせ「名」のみ差し替え
    • uint16なランダムIdの⽣成
    • ベンチマークなので uint16(atomic.AddUint64()) に変更

    View Slide

  38. チューニングの確認
    % go test -bench . -benchmem -benchtime 3s


    goos: darwin


    goarch: amd64


    pkg: github.com/kazeburo/bench


    cpu: Intel(R) Core(TM) i5-1038NG7 CPU @ 2.00GHz


    BenchmarkDo-8 24056054 138.3 ns/op 0 B/op 0 allocs/op


    BenchmarkDoMoto-8 306056 10851 ns/op 224 B/op 8 allocs/op


    PASS


    ok github.com/kazeburo/bench 7.234s
    アロケーションは0に、当初の80倍程度⾼速化
    1回あたりのアロケー
    ション回数(allocs/
    op)
    1回あたりのアロ
    ケーションで確保
    した容量(B/op)
    実⾏した回数 1回あたりの実⾏に掛か
    った時間(ns/op)

    View Slide

  39. GOGC
    • GoでGCを実⾏するヒープサイズの⽬標となるパラメータ
    • デフォルト 100 で⼤きくすることでGCの頻度を減らしCPUコストを下げる
    (メモリは増加する)
    # ./prsd-bench -P 53 -H 192.168.10.50 --time-duration 32s --max-workers 300 --max-length 8 --label 1 --
    zone x.y


    2023-03-11 18:18:56.526777432 +0900 JST m=+20.001327490 resolved: 0.000000 query/sec,


    refused 157012.900000 query/sec, failed 0.000000 query/sec


    # GOGC=500 ./prsd-bench -P 53 -H 192.168.10.50 --time-duration 32s --max-workers 300 --max-length 8 --
    label 1 --zone x.y


    2023-03-11 18:19:40.175067406 +0900 JST m=+20.001772051 resolved: 0.000000 query/sec,


    refused 178251.500000 query/sec, failed 0.000000 query/sec 最後の⼀押として使う

    View Slide

  40. まとめ
    • ⽔責め攻撃はやっかい
    • ベンチマーカは適切な情報(エラー)が取得可能であること
    • ベンチマークはテストでもある
    • ベンチマーク対象に負けないパフォーマンス 💪
    • Go⾔語で作る上でのパフォーマンスチューニング

    View Slide

  41. SAKURA internet
    ࣾձΛࢧ͑Δ

    ύϒϦοΫΫϥ΢υΛ

    Ұॹʹ࡞Γ·ͤΜ͔ʁ
    Perl, Go, Python
    インフラ基盤から
    フロントエンドまで
    採⽤強化中!
    さくらインターネットではエン
    ジ
    ニア採⽤を強化しています
    さくらインターネットは新たなアイ
    デ
    アの創出に強い熱意と情熱を持って挑戦するお客様を

    じ
    め、私たちとつな
    が
    りのあるす
    べ
    ての⼈たちのために、未来のある
    べ
    き姿を想い描きな
    が
    ら ―「やりたいこと」を「
    で
    きる」に変える ― あらゆるア
    プ
    ローチを “インターネッ
    ト”を通
    じ
    て提供します。
    詳しくはWebサイトにて、カジュアル⾯談もやってます 👉 www.sakura.ad.jp/lp/22engineer/

    View Slide

  42. ご清聴ありがとう
    ございました
    このあとはさくらインターネットのブースにおります。
    質問などありましたらお気軽に~

    View Slide