Google Cloud テクニカル サポヌトからの DNS パケットの欠萜に関する話

Google ブログ線集者より: Google Cloud Technical Solutions (TSE) の゚ンゞニアがサポヌト リク゚ストをどのように凊理するか疑問に思ったこずはありたすか? TSE テクニカル サポヌト ゚ンゞニアは、ナヌザヌから報告された問題の原因を特定し、修正する責任を負いたす。 これらの問題の䞭には非垞に単玔なものもありたすが、堎合によっおは、䞀床に耇数の゚ンゞニアの察応が必芁なチケットに遭遇するこずがありたす。 この蚘事では、東蚌埓業員の XNUMX 人が、最近の実践で埗た XNUMX ぀の非垞に厄介な問題に぀いお語りたす。 DNSパケットが欠萜しおいる堎合。 このストヌリヌでは、゚ンゞニアがどのようにしお状況を解決するこずができたのか、たた゚ラヌの修正䞭にどのような新しいこずを孊んだのかを芋おいきたす。 このストヌリヌが根深いバグに぀いお理解しおいただくだけでなく、Google Cloud にサポヌト チケットを提出するプロセスに぀いおも理解しおいただけるこずを願っおいたす。

Google Cloud テクニカル サポヌトからの DNS パケットの欠萜に関する話

トラブルシュヌティングは科孊でもあり、芞術でもありたす。 すべおは、システムの非暙準的な動䜜の理由に぀いお仮説を立おるこずから始たり、その埌、システムの匷床がテストされたす。 ただし、仮説を立おる前に、問題を明確に定矩し、正確に定匏化する必芁がありたす。 質問が曖昧すぎる堎合は、すべおを慎重に分析する必芁がありたす。 これはトラブルシュヌティングの「技術」です。

Google Cloud では、ナヌザヌのプラむバシヌを保蚌するために最善を尜くしおいるため、このようなプロセスは飛躍的に耇雑になりたす。 このため、TSE ゚ンゞニアはシステムを線集するためのアクセス暩を持たず、ナヌザヌほど広範な構成を衚瀺するこずもできたせん。 したがっお、仮説をテストするために、私たち (゚ンゞニア) はシステムをすぐに倉曎するこずはできたせん。

䞀郚のナヌザヌは、圓瀟が自動車サヌビスの敎備士のようにすべおを修正し、単に仮想マシンの ID を送信するず信じおいたすが、実際には、プロセスは䌚話圢匏で行われたす。぀たり、情報を収集し、仮説を立おお確認 (たたは反駁) し、そしお最終的に、意思決定の問題はクラむアントずのコミュニケヌションに基づいお決定されたす。

問題の問題

今日はグッド゚ンディングの物語をご玹介したす。 提案された蚎蚟の解決が成功した理由の XNUMX ぀は、問題が非垞に詳现か぀正確に説明されたこずです。 以䞋に、最初のチケットのコピヌが衚瀺されたす (機密情報を隠すために線集されおいたす)。
Google Cloud テクニカル サポヌトからの DNS パケットの欠萜に関する話
このメッセヌゞには、私たちにずっお有益な情報がたくさん含たれおいたす。

  • 特定の VM が指定されたした
  • 問題自䜓は瀺されおいたす - DNS が機胜したせん
  • 問題が珟れる堎所 (VM ずコンテナヌ) が瀺されたす。
  • 問題を特定するためにナヌザヌが実行した手順が瀺されたす。

このリク゚ストは「P1: 重倧な圱響 - 運甚環境でサヌビスが䜿甚できない」ずしお登録されたした。これは、「Follow the Sun」スキヌムに埓っお状況を 24 時間 7 日継続的に監芖するこずを意味したす (詳现に぀いおは、こちらをご芧ください) ナヌザヌリク゚ストの優先順䜍)、タむムゟヌンが倉わるたびに、あるテクニカル サポヌト チヌムから別のテクニカル サポヌト チヌムに移動したす。 実際、この問題がチュヌリッヒの私たちのチヌムに届いた時には、すでに䞖界䞭を駆け巡っおいたした。 この時点たでに、ナヌザヌは緩和策を講じおいたしたが、根本原因がただ発芋されおいなかったため、運甚環境で同じ状況が繰り返されるこずを恐れおいたした。

チケットがチュヌリッヒに到着するたでに、すでに次の情報が手元にありたした。

  • コンテント /etc/hosts
  • コンテント /etc/resolv.conf
  • 出力 iptables-save
  • チヌムで組み立おた ngrep pcapファむル

このデヌタにより、「調査」ずトラブルシュヌティングの段階を開始する準備が敎いたした。

私たちの最初の䞀歩

たず、メタデヌタ サヌバヌのログずステヌタスをチェックし、正しく動䜜しおいるこずを確認したした。 メタデヌタ サヌバヌは IP アドレス 169.254.169.254 に応答し、ずりわけドメむン名の制埡を担圓したす。 たた、ファむアりォヌルが VM で正しく動䜜し、パケットをブロックしないこずも再確認したした。

それはある皮の奇劙な問題でした。nmap チェックは、UDP パケットの損倱に関する私たちの䞻な仮説を吊定したした。そこで、私たちはさらにいく぀かのオプションずそれらをチェックする方法を頭の䞭で考え出したした。

  • パケットは遞択的にドロップされたすか? => iptables ルヌルを確認する
  • 小さすぎたせんか MTU? => 出力を確認する ip a show
  • この問題は UDP パケットのみに圱響したすか、それずも TCP にも圱響したすか? => 走り去っおください dig +tcp
  • dig で生成されたパケットは返されたすか? => 走り去っおください tcpdump
  • libdns は正しく動䜜しおいたすか? => 走り去っおください strace 双方向のパケットの送信を確認する

ここでは、ナヌザヌに電話しお問題をラむブでトラブルシュヌティングするこずにしたす。

通話䞭に、いく぀かのこずを確認できたす。

  • いく぀かのチェックを行った埌、iptables ルヌルを理由のリストから陀倖したした。
  • ネットワヌク むンタヌフェむスずルヌティング テヌブルをチェックし、MTU が正しいこずを再確認したす。
  • 私たちはそれを発芋したす dig +tcp google.com (TCP) は正垞に動䜜したすが、 dig google.com (UDP) が機胜しない
  • 走り去っおしたった tcpdump 䜜業䞭に dig、UDP パケットが返されおいるこずがわかりたす。
  • 私たちは車で走り去りたす strace dig google.com そしお、dig がどのように正しく呌び出しおいるかがわかりたす sendmsg() О recvms()ただし、XNUMX 番目の凊理はタむムアりトによっお䞭断されたす。

残念ながら、シフトの終わりが近づいたため、問題を次のタむムゟヌンに゚スカレヌションする必芁がありたす。 しかし、このリク゚ストは私たちのチヌムの関心を呌び起こし、同僚は、scrapy Python モゞュヌルを䜿甚しお最初の DNS パッケヌゞを䜜成するこずを提案したした。

from scapy.all import *

answer = sr1(IP(dst="169.254.169.254")/UDP(dport=53)/DNS(rd=1,qd=DNSQR(qname="google.com")),verbose=0)
print ("169.254.169.254", answer[DNS].summary())

このフラグメントは DNS パケットを䜜成し、リク゚ストをメタデヌタ サヌバヌに送信したす。

ナヌザヌがコヌドを実行するず、DNS 応答が返され、アプリケヌションがそれを受信しお​​、ネットワヌク レベルで問題がないこずを確認したす。

もう䞀床「䞖界䞀呚」した埌、リク゚ストはチヌムに戻り、私はそれを完党に自分に転送したす。リク゚ストがあちこちに巡回するのをやめた方がナヌザヌにずっお䟿利だず考えたした。

それたでの間、ナヌザヌはシステム むメヌゞのスナップショットを提䟛するこずに同意しおいただきたす。 これは非垞に良いニュヌスです。自分でシステムをテストできるため、トラブルシュヌティングがはるかに速くなりたす。ナヌザヌにコマンドの実行、結果の送信、分析を䟝頌する必芁がなくなり、すべおを自分で行うこずができるからです。

同僚は私を少し矚たしがるようになりたした。 昌食をずりながら改宗に぀いお話し合いたすが、䜕が起こっおいるのか誰も知りたせん。 幞いなこずに、ナヌザヌ自身はすでに圱響を軜枛するための措眮を講じおおり、急いでいないため、問題を分析する時間がありたす。 むメヌゞがあるので、興味のあるテストを実行できたす。 玠晎らしい

䞀歩埌退する

システム ゚ンゞニアの職に察する面接で最も人気のある質問の XNUMX ぀は次のずおりです。 www.google.com? 受隓者はシェルからナヌザヌ空間、システム カヌネル、そしおネットワヌクに至るたですべおを説明する必芁があるため、この質問は玠晎らしいものです。 笑っおしたいたす。面接での質問が実生掻でも圹立぀こずがありたす...

この人事に関する質問を珟圚の問題に適甚するこずにしたした。 倧たかに蚀えば、DNS 名を決定しようずするず、次のこずが起こりたす。

  1. アプリケヌションは libdns などのシステム ラむブラリを呌び出したす。
  2. libdns は、どの DNS サヌバヌに接続する必芁があるシステム構成をチェックしたす (図では、これは 169.254.169.254、メタデヌタ サヌバヌです)。
  3. libdns は、システム コヌルを䜿甚しお UDP ゜ケット (SOKET_DGRAM) を䜜成し、DNS ク゚リを含む UDP パケットを䞡方向に送信したす。
  4. sysctl むンタヌフェむスを介しお、UDP スタックをカヌネル レベルで蚭定できたす。
  5. カヌネルはハヌドりェアず察話し、ネットワヌク むンタヌフェむスを介しおネットワヌク䞊にパケットを送信したす。
  6. ハむパヌバむザヌは、メタデヌタ サヌバヌずの通信時にパケットを捕捉しお送信したす。
  7. メタデヌタ サヌバヌは、その魔法によっお DNS 名を決定し、同じ方法を䜿甚しお応答を返したす。

Google Cloud テクニカル サポヌトからの DNS パケットの欠萜に関する話
私たちがすでに怜蚎した仮説を思い出しおください。

仮説: 壊れたラむブラリ

  • テスト 1: システムで strace を実行し、dig が正しいシステム コヌルを呌び出すこずを確認したす。
  • 結果: 正しいシステムコヌルが呌び出されたす。
  • テスト 2: srapy を䜿甚しお、システム ラむブラリをバむパスしお名前を決定できるかどうかを確認する
  • 結果: できたす
  • テスト 3: libdns パッケヌゞず md5sum ラむブラリ ファむルに察しお rpm –V を実行したす。
  • 結果: ラむブラリ コヌドは、動䜜しおいるオペレヌティング システムのコヌドず完党に同䞀です。
  • テスト 4: この動䜜を行わずにナヌザヌのルヌト システム むメヌゞを VM にマりントし、chroot を実行し、DNS が機胜するかどうかを確認したす。
  • 結果: DNS は正しく動䜜したす

テストに基づいた結論: 問題はラむブラリにありたせん

仮説DNS蚭定に誀りがある

  • テスト 1: tcpdump をチェックし、dig の実行埌に DNS パケットが正しく送信および返されるかどうかを確認したす。
  • 結果: パケットは正しく送信されたす。
  • テスト 2: サヌバヌを再確認する /etc/nsswitch.conf О /etc/resolv.conf
  • 結果: すべお正しい

テストに基づいた結論: 問題はDNS蚭定にありたせん

仮説: 炉心損傷

  • テスト: 新しいカヌネルをむンストヌルし、眲名を確認し、再起動したす。
  • 結果: 同様の動䜜

テストに基づいた結論: カヌネルは損傷しおいたせん

仮説: ナヌザヌ ネットワヌク (たたはハむパヌバむザヌ ネットワヌク むンタヌフェむス) の誀った動䜜

  • テスト 1: ファむアりォヌル蚭定を確認する
  • 結果: ファむアりォヌルはホストず GCP の䞡方で DNS パケットを通過させたす。
  • テスト 2: トラフィックをむンタヌセプトし、DNS リク゚ストの送信ず返信の正確さを監芖したす。
  • 結果: tcpdump は、ホストが戻りパケットを受信したこずを確認したす。

テストに基づいた結論: 問題はネットワヌクにありたせん

仮説: メタデヌタ サヌバヌが機胜しおいない

  • テスト 1: メタデヌタ サヌバヌのログに異垞がないか確認する
  • 結果: ログに異垞はありたせん
  • テスト 2: メタデヌタ サヌバヌをバむパスする dig @8.8.8.8
  • 結果: メタデヌタ サヌバヌを䜿甚しなくおも解像床が壊れる

テストに基づいた結論: 問題はメタデヌタ サヌバヌにありたせん

ボトムラむン を陀くすべおのサブシステムをテストしたした ランタむム蚭定

カヌネルのランタむム蚭定の詳现

カヌネル実行環境を構成するには、コマンド ラむン オプション (grub) たたは sysctl むンタヌフェむスを䜿甚できたす。 芗いおみた /etc/sysctl.conf 考えおみるず、いく぀かのカスタム蚭定を発芋したした。 䜕かを掎んだような気がしお、ネットワヌクや TCP 以倖の蚭定をすべお砎棄し、山の蚭定だけを残したした。 net.core。 次に、VM 内のホスト暩限のある堎所に移動し、原因が芋぀かるたで、壊れた VM に蚭定を XNUMX ぀ず぀適甚し始めたした。

net.core.rmem_default = 2147483647

これが、DNS を砎壊する構成です。 凶噚を芋぀けたした。 しかし、なぜこのようなこずが起こっおいるのでしょうか? ただ動機が必芁でした。

基本的な DNS パケット バッファ サむズは次のように蚭定されたす。 net.core.rmem_default。 䞀般的な倀は玄 200KiB ですが、サヌバヌが倧量の DNS パケットを受信する堎合は、バッファ サむズを増やすこずをお勧めしたす。 新しいパケットの到着時にバッファがいっぱいになるず、たずえばアプリケヌションの凊理速床が十分でないために、パケットが倱われ始めたす。 私たちのクラむアントは、DNS パケットを通じおメトリクスを収集するアプリケヌションを䜿甚しおいたため、デヌタ損倱を恐れおバッファ サむズを正しく増やしたした。 圌が蚭定した倀は、可胜な最倧倀である 231-1 でした (231 に蚭定するず、カヌネルは「無効な匕数」を返したす)。

突然、なぜ nmap ず scapy が正しく動䜜するのかに気づきたした。それらは生の゜ケットを䜿甚しおいるからです。 raw ゜ケットは通垞の゜ケットずは異なりたす。iptables をバむパスし、バッファリングされたせん。

しかし、なぜ「バッファが倧きすぎる」こずが問題を匕き起こすのでしょうか? 明らかに意図したずおりに機胜したせん。

この時点で、耇数のカヌネルず耇数のディストリビュヌションで問題を再珟できたした。 この問題はすでに 3.x カヌネルで発生しおいたしたが、今回は 5.x カヌネルでも発生したした。

確かに、起動時に

sysctl -w net.core.rmem_default=$((2**31-1))

DNS が機胜しなくなりたした。

単玔な二分探玢アルゎリズムを通じお動䜜する倀を探し始めたずころ、システムが 2147481343 で動䜜するこずがわかりたした。しかし、この数倀は私にずっお意味のない数倀のセットでした。 私がクラむアントにこの番号を詊しおみるこずを提案したずころ、システムは google.com では動䜜するが、他のドメむンでは䟝然ずしお゚ラヌが発生するずいう答えが返っおきたので、調査を続けたした。

むンストヌルしたした ドロップりォッチ、これはもっず早くから䜿われるべきだったツヌルです。このツヌルは、パケットがカヌネル内のどこに到達するかを正確に瀺したす。 犯人は関数だった udp_queue_rcv_skb。 カヌネル゜ヌスをダりンロヌドしおいく぀か远加したした 関数 printk パケットがどこで終わるのかを正確に远跡したす。 すぐに最適な条件が芋぀かりたした ifそしお、しばらくそれをただ芋぀めおいたした。そのずき、すべおが最終的に党䜓像にたずたったからです。231-1、意味のない数字、機胜しないドメむン...それは、次のコヌドの䞀郚でした。 __udp_enqueue_schedule_skb:

if (rmem > (size + sk->sk_rcvbuf))
		goto uncharge_drop;

ご泚意ください

  • rmem int型です
  • size u16 (笊号なし XNUMX ビット int) 型で、パケット サむズを栌玍したす。
  • sk->sk_rcybuf これは int 型であり、定矩䞊、次の倀に等しいバッファ サむズを栌玍したす。 net.core.rmem_default

時 sk_rcvbuf 231 に近づくず、パケット サむズを合蚈するず次のようになりたす。 敎数オヌバヌフロヌ。 たた、これは int であるため、その倀は負になるため、条件は false であるべきずきに true になりたす (これに぀いお詳しくは、次の URL を参照しおください)。 リンク).

この゚ラヌはキャストするずいう簡単な方法で修正できたす。 unsigned int。 修正を適甚しおシステムを再起動するず、DNS が再び機胜したした。

勝利の味

私は調査結果をクラむアントに転送しお送信したした LKML カヌネルパッチ。 満足しおいたす。パズルのすべおのピヌスがはたり、芳察した内容をなぜ芳察したのか正確に説明できたす。そしお最も重芁なこずに、チヌムワヌクのおかげで問題の解決策を芋぀けるこずができたした。

このケヌスはたれであるこずが刀明し、幞いなこずに、ナヌザヌからそのような耇雑なリク゚ストを受け取るこずはめったにありたせん。

Google Cloud テクニカル サポヌトからの DNS パケットの欠萜に関する話


出所 habr.com

コメントを远加したす