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

Linux Networking Tools: 101

OpenJNY
September 04, 2020

Linux Networking Tools: 101

OpenJNY

September 04, 2020
Tweet

More Decks by OpenJNY

Other Decks in Technology

Transcript

  1. ping traceroute telnet curl tcpdump nmap dig netcat (nc) netstat

    ss ip arp whois lsof dhclient これらすべてのコマンドの man ページをちゃんと読んだことがある人にはこのスライドは必要ありません
  2. Unix: • 昔々、オペレーティングシステムは複雑で扱いにくいものでした。 • 1960年代後半のある日、Ken Thompson、Dennis Ritchie、そして AT&T Bell Labs

    の数人の同僚が、PDP-7でゲームを実行するために、よりシンプルなバージョンの Multicsを書くことに決めた。 • AT&T はコードの権利を持っており、ライセンスは高価でした。他の多くの企業 (DEC、HP、IBM、Sun) がUnixをサブライセンスし、独自のバージョンを販売していました。 • Unixの亜種は独自の拡張機能を追加し、しばしばお互いのアイデアや学界のアイデアを盗用していました。 BSD / GNU: • 一方、UC バークレーでは、何人かの学者がライセンスの状況に不満を持ち、AT&Tのライセンスコードを一切含まない Unix のバージョンを作ることにしました。 • こうして1980年代初頭には、 BSD (Berkeley Software Distribution) が Unix の自由な変形版となりました。 • BSDは最初、PDP-11やVAXenのようなミニコンピュータで動作しました。 • 一方、東海岸では、リチャード・ストールマンがプリンタドライバのソースコードを手に入れられずに大騒ぎになりました。 • 彼は1983年に GNU (GNUはUnixではありません)プロジェクトを立ち上げ、自由な Unix に似たオペレーティング・システムを作ることを意図しました。 • GNU プロジェクトの多くのコンポーネントは、現在のすべての自由なUnix、特にコンパイラGCCに含まれています。 Linux: • 一方、フィンランドでは、リーナス・トーバルズ (Linus Torvalds) は1991年の夏、ハッキングに夢中になりました。 • 彼は自分のPC用のオペレーティング・システムを書き、それを linux というディレクトリの FTP サーバに置いて共有することにしました。 • 多くの人々が Linux カーネル、多くの GNU プログラム、X ウィンドウ・システム、その他の自由ソフトウェアを含むソフトウェア・ディストリビューションを作成しました。 • これらのディストリビューション (Slackware, Debian, Red Hat, SUSE, Gentoo, Ubuntuなど) は、人々が一般的に「Linux」と言うときに参照するものです。 • ほとんどのLinuxディストリビューションは、 自由に発言できるソフトウェアで構成されていますが、自由に発言できるソフトウェアが存在しない場合には、ビールのように自 由に発言できるソフトウェアが含まれていることがよくあります。 Others: • 現在存在する他の Unix には、BSD の様々なフォーク (FreeBSD、NetBSD、OpenBSD から選択できますが、これらはすべてフリーでオープンで、ネットを通じて開発され ています) や、サーバを対象とした商業的な亜種の数が少なくなってきています。 • もうひとつのプロプライエタリな Unix ベースのオペレーティングシステムは、 Apple のデスクトップ、ラップトップ、PDA 上で動作する Mac OS X です。 https://unix.stackexchange.com/questions/3196/evolution-of-operating-systems-from-unix/3202
  3. The UNIX Philosophy: プログラム設計思想 プログラムは フィルタ “非”対話的 インターフェイス スモール・イズ・ ビューティフル

    プログラムは 一つをこなす 機能が少ない (小さい) プログ ラムはわかりやすく、保守しや すい。また他のプログラムとも 組み合わせることが出来る。 1つのことを上手くこなすことに 注力してプログラムは設計す べき。そうすれば自然と小さい プログラムになる。 プログラムはデータを作らない。 コンピュータは、ある形式の データを加工して、他の形式 で吐き出すものにすぎない。 対話的プログラムは大きく、 ユーザーが人間であることを仮 定するため、他のプログラムと の結合を妨げる。 Mike Gancarz 『UNIX という考え方』 より
  4. 注意点: ディストリビューションによる差異 • 本スライドでは、Linux のトラブルシューティングで使える情報収集ツールを紹介している • つまり、状態を観測するためのツール • 情報を集めるツールに関してはディストリビューション差は基本ない (別途インストールが必要なソフトウェアに

    関しては、インストール時のパッケージ管理方法は異なる) • ただ、構成を変更 (さらにそれを永続化する) する方法については、Linux のディストリビューショ ンによって設定方法が異なる場合がほとんど • 例えばネットワーク インターフェイスで IP アドレスを静的に設定する場合 • Debian 系: /etc/network/interfaces • RHEL/CentOS 系: /etc/sysconfig/network-scripts/ifcfg-eth0
  5. カーネルのバージョン $ uname -r 5.4.0-1023-azure $ uname -a Linux vm-bastion

    5.4.0-1023-azure #23~18.04.1-Ubuntu SMP Thu Aug 20 14:46:48 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux $ cat /proc/version Linux version 5.4.0-1023-azure (buildd@lgw01-amd64-053) (gcc version 7.5.0 (Ubuntu 7.5.0- 3ubuntu1~18.04)) #23~18.04.1-Ubuntu SMP Thu Aug 20 14:46:48 UTC 2020 # installed kernels $ ls /lib/modules/ 5.0.0-1032-azure 5.0.0-1036-azure 5.3.0-1022-azure 5.4.0-1023-azure 5.0.0-1035-azure 5.3.0-1020-azure 5.3.0-1034-azure
  6. OS のバージョン $ cat /etc/*release DISTRIB_ID=Ubuntu DISTRIB_RELEASE=18.04 DISTRIB_CODENAME=bionic DISTRIB_DESCRIPTION="Ubuntu 18.04.4

    LTS" NAME="Ubuntu" VERSION="18.04.4 LTS (Bionic Beaver)" ID=ubuntu ID_LIKE=Debian PRETTY_NAME="Ubuntu 18.04.4 LTS" VERSION_ID="18.04" HOME_URL="https://www.ubuntu.com/" SUPPORT_URL="https://help.ubuntu.com/" BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/" PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy" VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic $ lsb_release --all No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 18.04.4 LTS Release: 18.04 Codename: bionic
  7. なぜ Linux を学ぶ必要があるのか? Linux is the future 30 年以上の歴史があるにも関わらず、まだまだ人気の衰えがない Linux

    is on everything インターネット上の 2/3 以上のサーバーは Linux Android、ネットワーク機器、99 % のスパコン、IoT デバイス、Tesla cars、Play Station Linux is adaptable モジュール性があり OSS であるという性質から、様々な用途に使える Linux has a strong community and ecosystem OSS 故の協力なエコシステムがあり、学習にも向いている
  8. 用語 • NIC (network interface card): インターフェイス ポート (interface port)

    をもつ物理デバイス。ポートには DMA コントローラーがあり、CPU とメモリを共有している • パケット (packet): 一般に IP レベルのルーティングできるメッセージ • フレーム (frame): インターフェイスが扱うレベル (e.g. Ethernet) でのメッセージ • 帯域幅 (bandwidth): ネットワーク端点のデータ転送速度の上限。通常は bps (bits per second) で 計測される。例えば 10 GbE は、帯域幅が 10 Gbps のイーサネットのこと • スループット (throughput): ネットワーク端点間の現在のデータ転送速度。通常は bps で計測される。 • レイテンシ (latency): メッセージが端点間で往復するのにかかる時間。ラウンドトリップタイム (RTT) や ping 遅延とも言う。上位プロトコルの観点で、接続準備 (e.g. TCP の 3-way handshake) にかかる時 間を指す場合もある。 • TX/RX: アプリケーションから見たときのパケット移動方向。Transmit (送信) と Receive (受信) Brendan Gregg 『詳解 システム・パフォーマンス』 第10章 より
  9. Linux のネットワークスタック • ソケット: ユーザーアプリケーションにとってのデータ送信/受信のエンドポイント。 send/recv のために、ソケット バッファとよばれる queue (RX/TX

    で) を持っている • TCP (Transmission Control Protocol): 順序通り、信頼できる仮想コネクションで、 完全性を保ったままデータを送受信するためのトランスポート プロトコル • UDP (User Datagram Protocol): TCP のようなオーバーヘッドがない、メッセージ転送の ためのシンプルなトランスポート プロトコル • IP (Internet Protocol): ネットワーク ホスト間でパケットを転送するためのプロトコル • ICMP (Internet Control Message Protocol): IP を補助するために、エラー等を送受 信するネットワーク プロトコル • Queueing Discipline: トラフィック制御、スケジューリング、操作、フィルタのためのオプ ショナルなレイヤー (a.k.a. TC)。RX/TX のそれぞれで qdisc をもつ。 • デバイス ドライバ: RX/TX の 2 つの Ring Buffer (ドライバーキュー) をもつ • NIC (network interface card): 物理的なネットワークポートを持つデバイス。tunnels、 veths, loopback といったような仮想デバイスであることもある。NIC 自体も TX queue を持っていたりするがあまり関係ない Brendan Gregg “BPF Performance Tools: Linux System and Application Observability” – Chapter 10
  10. パケットの RX (Receiving) プロセス https://indico.cern.ch/event/408139/contributions/979737/attachments/815628/1117588/CHEP06.pdf 1. DMA によって、NIC に到着した電気信号が Socket

    Kernel Buffer (SKB) に変換され、カーネ ルメモリ中の RX Ring Buffer に転送される 2. (NAPI が有効でない限り) NIC はすかさずハードウェア割り込みを行う。パケットが来た事を CPU 伝え、ソフトウェア割り込みをスケジュールさせる (poll_queue にタスクをひとつ追加)。 3. poll_queue を定期的に監視している SoftIRQ がタスクを発見 (ソフトウェア割り込み) すれ ば、いよいよカーネルが本格的にパケット処理を開始する。 4. カーネルのネットワークスタック (IP+TCP/UDP/ICMP) でパケットを処理して、RX ソケットバッ ファ (sk_buff) にデータを挿入。もちろん IP の処理で forward されたら、折り返して TX Ring Buffer にパケットが挿入される。 5. アプリケーションが read/recv を呼び出して、ソケットバッファからデータを受信する。
  11. ネットワークスタックのバイパス技術 XDP (eXpress Data Path) Intel DPDK (Data Plane Development

    Kit) TC Ingress の前に BPF は発火できるので、実質 XDP は Queuing Discipline の さらに手前の (NIC に近い) 層に存在すると考えることが出来る
  12. USE メソッド • システムのボトルネックを見つけるためのトラブルシューティング方法論 • 詳解システムパフォーマンスで有名な Gregg 氏が考案 • “ボトルネックを見つけるために、パフォーマンス調査の初期の段階で使うべきメソドロジ”

    • すべてのリソース (コンポーネント)について Usage/Saturation/Error を調査する • Usage (使用率): 決められたインターバルの中で、リソースがビジーだった時間の割合 • Saturation (飽和): 処理できない要求を抱えている度合い (キューの現在の長さ) • Error (エラー): エラーイベントの回数 • エラー ⇒ 飽和 ⇒ 使用率 の順番で確認するのが効果的 http://www.brendangregg.com/USEmethod/use-linux.html
  13. ping • ネットワーク ホストに ICMP Echo Request を送信するコマンド • 4.3BSD

    で初めて導入されたコマンド • OS やディストリビューションによって標準搭載されている ping ソフトウェアが異なる点に注意 • 例えば、Windows の ping は既定で有限回数しか送信しない一方、Linux の ping(8) は -c オプションを指 定しない限り送信を続ける • 宛先指定は FQDN でも IP アドレスでも可 • いくつかの統計量もあわせて出力してくれる • ロス率: 何 % のパケットがロスしたか • Ping RTT (route trip time): ホスト間の往復に平均何 ms かかるか • 任意のホストが ICMP に応答すると仮定するのはよくある誤解 • 例) Windows OS では既定で Windows Firewall が ICMP をブロック • 例) Azure Load Balancer は ICMP に対応しない • 疎通確認する際は、相手ホストが応答すると期待されるプロトコルを必ず使うこと
  14. # Basic Usage $ ping host.example.com $ ping 10.5.0.5 #

    Send exact N packets and stop $ ping –c 5 google.com # Change packet size (<size> + 20 + 8 = actual bytes) $ ping –s 100 host.example.com # Flood the network $ sudo ping -f host.example.com
  15. traceroute • 指定したホストまでの IP ネットワークの経路 (ゲートウェイ、ルーターの列) を検出する • Time To

    Live (TTL) を一つずつ増やしながら (初期値は TTL = 1) パケットを送出 • ICMP TIME_EXCEEDED を返却するルーターを近い順番から列挙する • Round Trip Time (RTT) や Gateway のアドレスを知るために各 TTL で 3 回パケットを送信 • 同じクライアントから traceroute しても結果が異なる場合がある点に注意 • 毎回同じホップ経路でパケットがフォワーディングされる保証はない • 対応プロトコルは UDP/TCP/ICMP • Linux の traceroute は既定で UDP のパケット (既定ポート 53) を送信 • オプションで TCP (-T; 既定ポートは 80) や ICMP (--icmp) に変えることができる • Azure VNet 環境ではしばしば ICMP が使えないので適宜プロトコルを変更するのが吉 • 例) Azure Load Balancer は ICMP 非対応
  16. # Basic Usage $ traceroute host.example.com $ traceroute 10.5.0.5 $

    traceroute –p 1234 host.example.com # ICMP $ traceroute –-icmp host.example.com # TCP $ traceroute –T –p 443 host.example.com # IPv6 $ traceroute -6 host.example.com
  17. telnet • TELNET プロトコルのクライアント ソフトウェア • ARPANET の誕生から 1 年も立たないうちに出てきた老舗のプロトコル

    • クライアント サーバー モデルに基づいており、テキストベースでの対話を提供する • リモートからマシン (メインフレームなど) を管理できる点から重宝された • SSH が登場して置換されたが、セキュリティが無視できる場合は未だに使われることも • 使いみち • 図書のオンラインカタログ (e.g. OPAC) • アプリケーションとのテキストベースの対話インターフェイス (e.g. チェスのゲーム) • ネットワーク機器の config を管理するためのインターフェイス • TELNET は TCP に基づいており、既定では 23 番ポートを使う • ポート番号を変更できることから TCP の疎通確認目的でも利用される
  18. curl • CLI ベースのデータ転送のためのクライアント ソフトウェア • ブラウザとして使われることが多いが、様々なデータ転送プロトコルに対応している • 実は最近のバージョンの Windows

    10 には curl.exe が内包されている • URI (RFC 3986) で宛先を指定できる • ftp://ftp.is.co.za/rfc/rfc1808.txt • http://www.ietf.org/rfc/rfc2396.txt • telnet://192.0.2.16:80/ <-- telnet も指定可能 • mailto:[email protected] • 複数の URL を一気に指定することも • http://site.{one,two,three}.com • ftp://ftp.example.com/file[a-z].txt • オプション多すぎるのでこまったときはチートシート • curl cheat.sh/curl
  19. # Basic Usage $ curl <url> # Echo IP $

    curl ifconfig.me # Cheat sheet (cheat.sh) $ curl cheat.sh/curl # Use telnet to check L4 connectivity $ curl –vv telnet://host.example.com:1234 # Post JSON $ curl -X POST 127.0.0.1:1234 ¥ -H 'Content-Type:application/json’ ¥ --data '{"key":"value"}'
  20. netcat (nc) • TCP/UDP/Unix-domain socket の connect/listen に関するユーティリティー コマンド •

    便利すぎて、しばしば “アーミーナイフ” と呼ばれることがある • 搭載機能 • TCP/UDP のサーバーモード、クライアントモード • ポートスキャニング • TELNET プロトコル対応 • stdout/stdin とのスムーズな連携 • 便利シナリオ • 手軽にサーバー/クライアントを準備したいとき • ささっとポートスキャンしたいとき (-vz オプションは暗記必須) • SSH 中にファイル転送するとき (nc を使えばわざわざ scp しなくてよい)
  21. # nc – CLIENT/SERVER # TCP server $ nc –l

    1234 $ while true; do; nc –l 1234; done $ printf ‘HTTP/1.1 200 OK¥n¥n%s’ “$(cat index.html)” | nc -l 80 # TCP client $ nc localhost 1234 # TCP client (port scanning mode) $ nc –zv localhost 1234
  22. # nc – CLIENT/SERVER # UDP server $ nc –ul

    1234 # UCP client $ nc –u host.example.com 1234 $ echo “hello” | nc –u host.example.com 1234
  23. # nc - Reverse-shell # server $ mkfifo /tmp/f $

    cat /tmp/f | /bin/sh –i 2>&1 | nc –l localhost 1234 > /tmp/f # client $ nc localhost 1234
  24. # nc – File Transmission # server $ nc -l

    1234 > filename.out # client $ nc -N host.example.com 1234 < filename.in
  25. # Port Scanning $ nc -zv host.example.com 22 Connection to

    host.example.com 22 port [tcp/ssh] succeeded! # Specify multiple ports $ nc -zv host.example.com 20-30 $ nc -zv host.example.com 22 80 443
  26. tcpdump • いわゆる packet sniffer というやつ。内部的には cBPF (classic Berkeley Packet

    Filter) と呼 ばれる Linux の動的トレーシング機能を使っている • トレーシングとは、Linux (kernel) で発生する様々なイベントを追跡すること • イベントの例の一つが、ソケットに対するパケットの受信や送信 • BPF はもともと BSD の機能で、Linux にも移植されている • tcpdump は libpcap と呼ばれるユーザーライブラリを介して BPF を操作している • “生 (raw)” のパケットに近いものが取れる • BPF でトリガーされるイベントは、カーネルの中で最もドライバに近い場所でのイベント • もちろん netfilter よりもドライバに近いので、forwarding されるパケットだろうが、iptables でドロップされるパ ケットだろうが関係なく、全受信パケットがスニッフィングできる • 逆に送信に関しても、確実にドライバに送信されたパケットを見ることができる • 送受信パケットが多いと、バッファが足りず tcpdump で拾い切れない時もあるので注意 • Process を kill したときの “packets dropped by kernel” を必ず見ること
  27. # Basic Usage $ sudo tcpdump <expression> # Recommended Usage

    # -i any: all devices # -nN: show ip addresses instead of host names $ sudo tcpdump <expression> –i any –nN # Write/read packets to/from file $ tcpdump –w dump.pcap –i any $ tcpdump –r dump.pcap # Filter health probes from Azure Load Balancer $ tcpdump –ni any host 168.63.129.16 and port <probe-port> and tcp
  28. nmap • Network mapper (nmap) は、ネットワーク探索やセキュリティ監査のためのツール • Windows/Linux の定番ポートスキャナーとして有名 •

    多くのホストに対しても、単一のホストに対しても、効率よく情報を収集できるような工夫が施されている • ポートスキャンだけでなく、ホスト/サービスが使っているソフトウェアを検証できる • どんなホストがネットワークに存在する? • どの OS で動いてるホスト? • どのアプリケーションのどのバージョンで提供してるサービス? • スキャン方式 • TCP SYN (-sS): いわゆるステルススキャン • TCP connect (-sT) : raw socket を使わないので特権ユーザーじゃなくてもいいけど低速 • TCP ACK (-sA): SYN は締め出すけど ACK は閉じてないポートがわかる • … • Zenmap (nmap を叩くための GUI アプリケーション) も有名
  29. # Basic Usage $ nmap <target> # -A: OS/version detection,

    script scanning, and tracert # -T4: faster execution $ nmap –A –T4 host.example.com # Ping scan only: -sP # Don't ping: -PN <- Use full if a host don't reply to a ping. # TCP SYN ping: -PS # TCP ACK ping: -PA # UDP ping: -PU # ARP ping: -PR $ nmap –PS host.example.com # OS detection $ nmap –O –osscan_guess host.example.com # Traceroute: $ nmap -traceroute [target]
  30. dig • DNS 関連のトラブルシューティング必須ツール • nslookup も有名だが、様々な理由から dig を使うことが推奨される •

    デフォルトで問い合わせる DNS サーバーは、DHCP で降ってきたり自分で設定した (おそらく キャッシュ) DNS サーバー • Azure VM の場合だと iDNS (168.63.129.16) が該当 • @ のオプションで問い合わせ先の DNS サーバーを変更することが出来る • キャッシュとかが気になるときは権威 DNS サーバーに問い合わせるようにする • BIND と呼ばれる DNS サーバーに関連するソフトウェア群に内包 • Berkeley Internet Name Domain で BIND • 4.3BSD で初めて実装されたソフトウェア
  31. # Basic Usage $ dig [@<dns-server>] <query> [<dns-record-type>] $ dig

    host.example.com # Query specific DNS record $ dig example.com {ANY|A|AAA|NS|MX|TXT|CNAME} # More/Less verbose $ dig host.example.com +noall +answer $ dig host.example.com +short # Trace DNS Path $ dig host.example.com +trace # Reverse look-up $ dig -x 209.132.183.81 # Use a specific DNS server $ dig @8.8.8.8 example.com
  32. [TIPS] Why not nslookup, but dig? • dig は OS

    標準の resolver library を使う (nslookup は独自の resolver を使う) • dig のほうが生に近い結果を出力してくれる。特に relevant flags 等の情報は nslookup では 取得できないどころか正しく解釈されない • dig の出力結果はパースしやすい • dig は BIND パッケージに内包されているため、利用可能な環境が多い • なお、「nslookup は既に deprecated されている」というのはよくある誤解
  33. [TIP] Force dig to resolve without using cache • DNS

    プロトコル自体にはキャッシュを使わずに問い合わせする仕組みはない • dig では以下の 2 通りの方法でキャッシュを使わずに問い合わせることができる ① 権威 DNS サーバーに直接レコードを聞きに行く $ dig example.com NS $ dig @ns.example.com example.com ② +trace オプションを使って問い合わせる $ dig +trace example.com https://serverfault.com/questions/372066/force- dig-to-resolve-without-using-cache
  34. netstat • net-tools と呼ばれるソフトウェア群の一つで、ホスト上の TCP/IP に関する情報を出力してく れるコマンド • ユーザープログラムが利用している socket

    の状態を表示している • Windows でもおなじみだが、オプションの指定方法が違ったりするので注意 • プラットフォームによるオプション差異は Wikipedia (EN) が詳しい • 使い所 • 確立済みの TCP コネクションの数を知りたい • 利用可能なエフェメラルポート数を知りたい • あるプロセスが通信しているリモート ホストのアドレスが知りたい • netstat で確認できる socket の種類 • TCP (AF_INET/AF_INET6 + SOCK_STREAM) • UDP (AF_INET/AF_INET6 + SOCK_DGRAM) • Unix domain socket (AF_UNIX + SOCK_STREAM/SOCK_DGRAM)
  35. TCP の状態遷移 • netstat の結果を正しく解釈するためには、TCP の状態遷移を知っておく必要がある • 詳しくは RFC 793

    を参照のこと • 状態の例 • CLOSED: netstat では表示されない • LISTEN: -l オプションを指定すると表示される。サーバー が socket を bind して listen するとこの状態 • ESTABLISHED: 3-way handshake が完了して、任意 のデータを送りあえる状態。サーバーが socket を accept して、クライアントが socket を connect すると ESTABLISHED になる • TIME_WAIT: コネクションを切った (socket を close し た) 側が、完全に socket を手放すまでの状態
  36. # Recommended (listening, tcp, udp, program, numeric) $ netstat –ltupn

    # List sockets in listening state $ netstat –-listening|-l # Filter by protocol (TCP, UDP, RawSocket) $ netstat –-tcp|-t, --udp|-u, --raw|-w # Use numeric address instead of hostname $ netstat --numeric|-n # List all ports $ netstat --all|–a $ netstat -a | grep ESTAB | wc –l # Show process $ netstat --program|–p # Continuously update results $ netstat --continuous|–c
  37. # インターフェイス統計量の表示 # --- # RX-*: 受信 # TX-*: 送信

    # # OK: 転送成功 # ERR: パケットエラー # DRP: パケットドロップ (インターフェイスの飽和の兆候) # OVR: パケットオーバーラン (インターフェイスの調和の兆候) $ netstat –i # 毎秒更新 $ netstat –i -c
  38. # ネットワーク スタック全体の統計量を表示 # --- # [注] total packets received

    (受信パケット総数) に対して forwarded (転送パケット吸う) の比率が高い: 意図的にルーターとして動作させているのか確認 # [注] passive connection openings (パッシブ TCP 接続): クライアント接続毎に負荷を確認 # [注] segments send out (セグメント送出) に対して segments retransmitted (セグメント再送出) が高 い: 信頼性の低いネットワークであると判断できる # [注] packets pruned from receive queue because of socket buffer overrun (受信のソケットバッ ファ オーバーラン): ネットワーク リソース飽和の兆候。ソケットバッファを増やすことで改善が期待できる $ netstat --statistics|–s # /proc/net から直接見る $ cat /proc/net/snmp $ cat /proc/net/netstat
  39. [TIP] TIME_WAIT • TCP コネクションをアクティブクローズした側は、最終的 に TIME_WAIT と呼ばれる状態で一定の時間待つ必 要がある •

    [理由] LAST_ACK からの再 FIN/ACK に対応する為 • ポート枯渇のチューニングでは、この wait 時間を調節 • TIME_WAIT の残時間を知りたかったら -o/--timers オ プションをつけて netstat するとよい • netstat -anpto | grep TIME_WAIT • TIME_WAIT のソケット数を知りたいだけなら /proc/net/sockstat の tw でも可 • cat /proc/net/sockstat | awk '$1 == "TCP:" {print $7}'
  40. [TIP] スループットなら sar • netstat で出力出来る統計量はあくまで “パケット数” の統計量 • スループットを知りたかったら他のコマンドを使う必要がある

    • ip -s link • sar -n DEV 1 • sar -n EDEV 1 • sar はプロトコル毎にも出力できるし、定期監視できるので便利 IFACE インタフェース名 rxpck/s 1秒間あたりの受信パケット数 txpck/s 1秒間あたりの送信パケット数 rxbyt/s 1秒間あたりの受信バイト数 txbyt/s 1秒間あたりの送信バイト数 rxcmp/s 1秒間あたりの圧縮受信パケット数 txcmp/s 1秒間あたりの圧縮送信パケット数 rxmcst/s 1秒間あたりのマルチキャスト受信パケット数
  41. [TIP] net-tools は obsolete • CentOS 7 以降ではもはや既定で netstat はインストールされない

    • net-tools (netstat/ifconfig/route/arp,…) のソフトウェアは廃止される方向 • ss や ip といった iproute2 の代替ツールを使うことが推奨されている • とはいえ他のエンジニアと話を合わせる為にも netstat を知っておかなければならない・・・ This program is mostly obsolete. Replacement for netstat is ss. Replacement for netstat –r is ip route. Replacement for netstat –i is ip –s link. Replacement for netstat –g is ip maddr. “ Ref: man netstat
  42. [TIP] なぜ iproute2 なのか? • 要は機能的にも優れていて、コマンドのデザイン的にもキレイだから • ほとんどのディストリビューションでは、net-tools (arp, ifconfig,

    route) を今でも使っているが、こ れらは古いプログラムで、最新の Linux カーネルでは期待通り動作しないことがある • 例えば、GRE トンネルは net-tools では対応できない • これは Linux の ver2.2 でネットワーク サブシステムが再設計されたことが大きく関与している • 当時 SunOS (solaris) を模倣していた Linux は、機能拡張する度にコードが複雑化していた • それを刷新する目的で Linux 2.2 ではイチからネットワークコンポーネントを設計しなおした • また iproute2 は net-tools に比べて遥かに一貫性のある API を提供する https://tldp.org/HOWTO/Adv-Routing-HOWTO/lartc.iproute2.why.html
  43. ss (socket statistics) • socket の状態を調べるためのツール • ss は iproute2

    と呼ばれるソフトウェア コレクションに含まれる • 特に TCP の状態/統計量のサマライズに強い • netstat の後継として知られていて、ほとんどオプションも一緒 • -4/-6 : IPv4/IPv6 指定 • -n : hostname ではなく IP アドレスで表示 • -l : LISTEN 状態のソケットを表示 • -a : LISTEN とそうでないソケットの両方を表示 • -t : TCP ソケットを表示 • -u : UDP ソケットを表示 • -w: Raw ソケットを表示 • -x : Unix ドメインソケットを表示 • -p : ソケットを使っているプロセスを表示 • TCP State や Src/Dst のアドレス・ポートでフィルタリングする機能がある
  44. # Show all TCP/UDP/RAW/UNIX sockets $ ss -a -t|-u|-w|-x #

    Recommended (listening, tcp, udp, process, no-resolve) $ ss –ltupn # Show all TCP sockets connected to the local HTTPS port (443) $ ss –t src :443 # Show a summary of all ports connecting to 192.168.2.1 via port 80. $ ss -t dst 192.168.2.1:80 # Show all SSH-related TCP connections $ ss -t state established '( dport = :ssh or sport = :ssh )’ # Filter connections by TCP state $ ss -t4 state established|closed|time-wait|
  45. [TIP] ss での -c/--continuous 代替方法 • netstat では -c (--contiuous)

    オプションで毎秒情報を更新できた • ss 自体には定期更新機能はないが、watch コマンドで代用できる $ watch –n 1 "ss –t4 state syn-sent" 1 秒ごとにプログラムを再実行し、フルスクリーンで表示する
  46. ip • ルーティング、ネットワーク デバイス、インターフェース、トンネル等のネットワーク オブジェクトを閲 覧したり操作するためのコマンド • ip は iproute2

    と呼ばれるソフトウェア コレクションに含まれる • net-tools (arp/ifconfig/route/ipmaddr/iptunnel/netstat) の後継 • 色々なことが出来る反面、出来ることが多すぎて覚えるのがやっかいという側面も • ただ、普段使うのは一部のオブジェクトの構成確認くらい • 構成変更等はその都度調べたら良い • コマンドは ip <OBJECT> <show|add|del|…> で統一されている
  47. ip <OBJECT> address Net Interface の IPv4/6 アドレス netns ネットワーク名前空間

    addrlabel IPv6 アドレス ラベル (RFC3484) ntable neighbor テーブルのパラメータ l2tp L2TPv3 イーサネット トンネル route ルーティング テーブル link ネットワーク デバイス rule ルーティング ポリシー maddress マルチキャストアドレス tcp_metrics TCP のパラメータ monitor ネットワーク構成情報の監視 token Tokenized IPv6 Identifier mroute マルチキャスト tunnel *over-IP のトンネル インターフェイス mrule マルチキャスト ルーティング ポリシー tuntap TUN/TAP 仮想デバイス neighbour ARP/NDISC キャッシュ テーブル xfrm XFRM ポリシー
  48. ip address • ネットワーク インターフェイスの IP アドレス の情報を確認/変更するコマンド • ifconfig

    (@net-tools) の代替コマンド • iproute2 の中心的存在 • Link の情報まで出してくれる • -s オプションで NIC に関する統計量を出力 • 以下を確認するときによく見る • 構成済みのデバイス名 • インターフェイスに割り当てられた IP アドレス • インターフィエスが所属するサブネット • MTUの設定値 • リンクの UP/DOWN
  49. # Show all addresses $ ip address show $ ip

    address show up $ ip address show dev eth0 # Add/remove a secondary interface address to the device ‘eth0’ $ ip address add 10.0.0.10/24 dev eth0 $ ip address del 10.0.0.10/24 dev eth0 # Show all interfaces $ ip link show # Link-up/down $ ip link set eth0 up|down # Statistics # ip –s link
  50. juyamagu@vm-bastion:~$ ip address show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu

    1500 qdisc mq state UP group default qlen 1000 link/ether 00:0d:3a:cc:e0:89 brd ff:ff:ff:ff:ff:ff inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20d:3aff:fecc:e089/64 scope link valid_lft forever preferred_lft forever インターフェイスの状態 - BROADCAST: ブロードキャストが有効になっている - MULTICAST: マルチキャストが有効になっている - UP: ネットワークインターフェイスが有効な状態 - LOWER_UP: デバイスにケーブルが繋がっている - RUNNING: デバイスが動作中 - LOOPBACK: ループバックデバイスである
  51. juyamagu@vm-bastion:~$ ip address show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu

    1500 qdisc mq state UP group default qlen 1000 link/ether 00:0d:3a:cc:e0:89 brd ff:ff:ff:ff:ff:ff inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20d:3aff:fecc:e089/64 scope link valid_lft forever preferred_lft forever mtu 1500 最大の IP パケットサイズ 。このリンクは Ethernet なので、さらにフレーム ヘッダ (14 bytes) と FCS (4 byte) が加算されてフレームが完成。 qdisc mq Queueing Discipline の略。送信スケジューリング方式が mq (multiqueue) scheduler であることを表す。tc コマンドで変更可能。 state UP ネットワーク インターフェイスの状態。UP は動作中を表す。ip link set eth0 down 等を実行すると DOWN になる。 group default グループインターフェイス qlen 1000 (/sys/class/net/eth0/tx_queue_len) 送信キュー (TX buffer ring) の長さで、Linux のデフォルトは 1000。あまり大きくしすぎるとスループットが下がる (詳しくは bufferbloat で gg ると幸せになれるかも)
  52. juyamagu@vm-bastion:~$ ip address show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu

    1500 qdisc mq state UP group default qlen 1000 link/ether 00:0d:3a:cc:e0:89 brd ff:ff:ff:ff:ff:ff inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20d:3aff:fecc:e089/64 scope link valid_lft forever preferred_lft forever link/ether イーサネットのリンクであることを表す。他には loopback (lo) や ppp0 がよくある link 種別。 00:0d:3a:cc:e0:89 MAC アドレス brd ff:ff:ff:ff:ff:ff ブロードキャスト MAC アドレス
  53. juyamagu@vm-bastion:~$ ip address show dev eth0 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu

    1500 qdisc mq state UP group default qlen 1000 link/ether 00:0d:3a:cc:e0:89 brd ff:ff:ff:ff:ff:ff inet 10.0.1.4/24 brd 10.0.1.255 scope global eth0 valid_lft forever preferred_lft forever inet6 fe80::20d:3aff:fecc:e089/64 scope link valid_lft forever preferred_lft forever inet 10.0.1.4/24 /24 のサブネットから払い出された 10.0.1.4 が割り当てられていることを表す。静的に割り振ったか、DHCP で降ってきたアドレス。 brd 10.0.1.255 上のアドレスに対するブロードキャスト アドレス scope global アドレスが有効な範囲。/etc/iproute2/rt_scopes に利用可能なスコープが列挙されているが、既定では global, site, link, host のいずれか。基本的に、Loopback interface なら host、 IPv4 なら global、IPv6 なら link となる。 eth0 Kernel として認識する (仮想) デバイスの名前 valid_lft forever アドレスの厳格な有効期限 (RFC 4862 のセクション 5.5.4 で規定)。既定は永久に有効 (forever)。もし期限に達したら Kernel が勝手に address を delete する。 preferred_lft foorever アドレスの望ましい有効期限 (RFC 4862 のセクション 5.5.4 で規定)。規定は永遠に有効 (forever)。もし期限に達したら、アドレスはそれ以降 outbound 通信に使われなくなる。
  54. juyamagu@vm-bastion:~$ ip -s link ... 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500

    qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:0d:3a:cc:e0:aa brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 129015723 173067 0 0 0 0 TX: bytes packets errors dropped carrier collsns 27561512 125820 0 0 0 0 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:1c:6d:63:4b brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 RX: bytes 正常に受信できたバイト数 packets 正常に受信できたパケット数 errors Ethernet の CRC エラーなど、NIC 上で処理できなかったパケット数。ケー ブルの破損等 dropped 意図的なドロップ。サポートしてないフレームや、IPv6 を無効化している 状態でやってきた IPv6 パケットを観測した数 overrun RX ring buffer の容量が足りずに破棄されたパケット数 mcast マルチキャスト通信を正常に受信した数
  55. juyamagu@vm-bastion:~$ ip -s link ... 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500

    qdisc mq state UP mode DEFAULT group default qlen 1000 link/ether 00:0d:3a:cc:e0:aa brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 129015723 173067 0 0 0 0 TX: bytes packets errors dropped carrier collsns 27561512 125820 0 0 0 0 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN mode DEFAULT group default link/ether 02:42:1c:6d:63:4b brd ff:ff:ff:ff:ff:ff RX: bytes packets errors dropped overrun mcast 0 0 0 0 0 0 TX: bytes packets errors dropped carrier collsns 0 0 0 0 0 0 TX: bytes 正常に送信できたバイト数 packets 正常に送信できたパケット数 errors Ethernet の CRC エラーなど、NIC 上で処理できなかったパケット数。ケー ブルの破損等 dropped 意図的なドロップ。サポートしてないフレームや、IPv6 を無効化している 状態でやってきた IPv6 パケットを観測した数 carrier NIC 内で何らかの問題 (e.g. ケーブルの接触不良) が生じて送信出来 なかったパケット数 collsns コリジョンを検知した (ジャム信号を送った) 回数
  56. ip rule: ポリシールール • RPDB (routing policy database) 内のポリシー ルール

    (rule) を閲覧/操作するコマンド • 従来のルート選択アルゴリズムは、パケットの宛先 IP アドレスや ToS フラグだけを使う • しかしながら、ソース IP やプロトコル等を使って、柔軟にルーティングしたいときがある • このようなタスクをポリシー ルーティング (policy routing) と呼ぶ • iproute2 では、ポリシー ルールを管理する DB を RPDB と呼んでいる • 各ポリシー ルール (rule) は、セレクターとアクションから成る • セレクター: アクションを実施したいパケットの条件を記述する • アクション: 実行したいことを記述する。特定の table から経路情報を lookup するアクションが一般的だが、 NAT を実施するアクションを指定したりもできる • ルーティングの流れ • 優先度 (priority) の小さい順で、RPDB 内のポリシー ルールを 1 つずつ見ていく • ルールのセレクターにパケットが合致する場合、アクションを実施する • アクションの実行に成功 (e.g. 経路情報を取得) できれば、RPDB の lookup は終了 • セレクターに合致しないか、アクションの実行に失敗すれば、次のポリシー ルールを見る
  57. ip route: ルーティングテーブル • ルーティング テーブルを確認/変更するためのコマンド • 経路情報はエントリーと呼ばれる • エントリーの集合がルーティング

    テーブル • 実は Linux (iproute2) は複数のルーティング テーブルを管理する • これもポリシー ルーティングのおかげ • 既定では local, main, default の 3 つの table が存在 • ip route add でテーブルを指定せずにルートを追加すると、main にルートが追加される • 既定で構成されるポリシー ルールと、規定のルーティング テーブル (local, main, default) は対 応付けられている
  58. 既定で構成されているポリシー ルール Priority Selector Action table に関するコメント 0 Any (全パケット)

    local テーブルを lookup local テーブルは、local と broadcast のため の特別なテーブル。Kernel が管理するので Admin が弄ることはない。 32766 Any (全パケット) main テーブルを lookup main テーブルはノンポリシー ルーティングの ためのルーティング テーブル。普通ルーティン グテーブルと言ったときはこれを指す。 32767 Any (全パケット) default テーブルを lookup default テーブルは既定で空。何も経路情 報がなかったときの post-process 用として 予約されているだけ。 順番にポリシールールを実行
  59. # Permanent configuration: routing table $ vi /etc/iproute2/rt_tables # Add

    new table $ echo 100 newtable >> /etc/iproute2/rt_tables # Show policy rules $ ip rule show # Show routing table (default: main) $ ip route show # Show all routing table $ ip route show table all # Perform route lookup on the specific destination $ ip route get 10.0.0.4 # Show only IPv4/6 entries $ ip route -4 show $ ip route -6 show # Add/remove a route $ ip route add 192.168.0.0/24 via 192.168.0.1 dev eth0 $ ip route del 192.168.0.0/24 via 192.168.0.1 dev eth0
  60. juyamagu@vm-bastion:~$ ip -4 route show table all default via 10.0.0.1

    dev eth0 proto dhcp src 10.0.0.4 metric 100 10.0.0.0/24 dev eth0 proto kernel scope link src 10.0.0.4 168.63.129.16 via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.4 metric 100 169.254.169.254 via 10.0.0.1 dev eth0 proto dhcp src 10.0.0.4 metric 100 broadcast 10.0.0.0 dev eth0 table local proto kernel scope link src 10.0.0.4 local 10.0.0.4 dev eth0 table local proto kernel scope host src 10.0.0.4 broadcast 10.0.0.255 dev eth0 table local proto kernel scope link src 10.0.0.4 broadcast 127.0.0.0 dev lo table local proto kernel scope link src 127.0.0.1 ... main table local table $1 (unicast|broadcast|local): エントリータイプ。unicast の場合は省略可能 $2 (x.x.x.x/x): 宛先アドレスプレフィクス $3 (via x.x.x.x): ネクストホップ。On-link の場合は省略可能 $4 (dev *): パケットが出力されるデバイス $5 (proto redirect|kernel|boot|static|ra): 誰がルートを作ったか。/etc/iproutue2/rt_protos で定義される PTPROTO のいずれか $6 (scope global|link|host|…): 宛先プレフィクスのスコープ。/etc/iproute2/rt_scopes のいずれか。省略すると global または link になる $7 (src x.x.x.x): 宛先に送信するときに優先して設定するソース IP アドレス $8 (metric *): ルートの優先度。小さい値のほうがより優先される
  61. [TIP] 複数 NIC を Azure Load Balancer 配下にする • 複数

    NIC 関連付けた Azure VM に対して、両方の NIC を Azure Load Balancer 配下とした いときがある • VM 内部からは eth0 と eth1 が見えている状態 • それぞれ別の Subnet に配置された NIC (Azure 上リソース) に対応する • この時 VM 内部では、168.63.129.16 や default からのパケットを適切な interface (device) から流してあげるように構成が必要 • eth0 に ALB 正常性プローブがきたら、eth0 から返す • eth0 にインターネット上クライアントからの ALB 経由アクセスがきたら、eth0 から返す • eth1 側も同様 • ここで policy ベースのルーティングが使える
  62. # ポリシー構成例 # ---------- # eth0 := 10.0.0.4/24 (gateway は

    10.0.0.1/24) # eth1 := 10.0.100.4/24 (gateway は 10.0.100.1/24) # table $ echo 200 eth0-rt >> /etc/iproute2/rt_tables $ echo 201 eth1-rt >> /etc/iproute2/rt_tables # policy rule $ ip rule add from 10.0.0.4/32 table eth0-rt $ ip rule add to 10.0.0.4/32 table eth0-rt $ ip rule add from 10.0.100.4/32 table eth1-rt $ ip rule add to 10.0.100.4/32 table eth1-rt # routing table entry $ ip route add 168.63.129.16 via 10.0.0.1 dev eth0 table eth0-rt $ ip route add default via 10.0.0.1 dev eth0 table eth0-rt $ ip route add 168.63.129.16 via 10.0.100.1 dev eth1 table eth1-rt $ ip route add default via 10.0.100.1 dev eth1 table eth1-rt
  63. arp • ARP のキャッシュ テーブルを確認/クリアするためのコマンド • 廃止される予定のコマンドなので特に覚える必要はない • 今後は ip

    neighbor を使うこと • ただやっぱり他のエンジニアと話を合わせるために・・・ • 個人的には、覚えるなと言われても覚えていざるを得ない名前をしていると思う • Azure VNet では L2 をユーザーが自由に構成できないので、ARP のキャッシュ テーブル自体確 認する必要が殆どない • なお、L2 ごとオーバーレイ仮想化している関係から、仮想 MAC アドレスをよく目にする • 12:34:56:78:90:AB のような奇妙な MAC アドレスがそれ
  64. [TIP] /proc/net/arp • arp や ip neighbor と同じ情報は /proc/net/arp からも取れる

    • 例) https://github.com/ItsJimi/go-arp $ sudo cat /proc/net/arp
  65. whois • whois ディレクトリサービスのクライアント • RFC 3912 で規定される WHOIS プロトコルを喋れるクライアント

    • 基本的にディストリビューションに内包されていることはなく、別途インストールが必要 • グローバル IP アドレスや AS 番号を所有している組織を調べることができる • 例) 8.8.8.8 は誰が所有 (管轄) している IP アドレス? • 管理している whois データベースを適切に指定することを忘れないように • -h オプションでデータベースのホスト名を指定する • 既定だと ARIN になる
  66. # Usage $ whois [–h <host>] <query> # Query $

    whois Mirosoft $ whois 98052 $ whois 12.107.136.0 # Other whois hosts $ whois –h whois.apnic.net <query> $ whois –h whois.nic.ad.jp <query>
  67. lsof • プロセスが開いているファイルの情報を収集する • Linux のファイル • レギュラー ファイル (regular

    file) • ディレクトリ (directory) • 特殊ファイル (block/character special file) • デバイス ファイル (device file) • パイプ (FIFO special file) • ソケット (socket) <-- Internet socket, Unix domain socket • -i オプションで Internet ソケットの情報を表示出来る
  68. # Usage $ lsof –i $ lsof –i [4|6] [tcp|udp][@hostname][:port]

    [-s(tcp|udp):STATE] # Unix domain socket も含めて表示 $ lsof –i –U # 8080 のローカルポートを開いてるプロセスを表示 $ lsof –i :8080 # 128.210.15.17 によって使用されている internet socket を表示 $ lsof –[email protected] # PID 1234 によって開かれているすべての IPv4 Internet socket を表示 $ lsof –i 4 –a –p 1234 # 8080/tcp でリッスン状態のソケットを表示 $ lsof –iTCP:8080 –sTCP:LISTEN
  69. dhclient • Dynamic Host Configuration Protocol (DHCP) に関連する操作を行うコマンド • DHCP

    で配信されている情報や、インターフェイスの静的な config を確認することで、インター フェイス設定が間違っていないかチェックできる • CentOS 系: /etc/sysconfig/network-scripts/ifcfg-eth0 • Debian 系: /etc/network/interfaces • 特に Azure だと静的に IP アドレスを付与するのはご法度なので注意 $ sudo dhclient –v Listening on LPF/eth0/00:0d:3a:cc:e0:89 Sending on LPF/eth0/00:0d:3a:cc:e0:89 Sending on Socket/fallback DHCPREQUEST of 10.0.0.4 on eth0 to 255.255.255.255 port 67 (xid=0x56bd5864) DHCPACK of 10.0.0.4 from 168.63.129.16 RTNETLINK answers: File exists bound to 10.0.0.4 -- renewal in 4294967295 seconds.
  70. jq

  71. [TIP] sudo で実行しろと怒られた時 • bash では !-n で n 個前の、!!

    で直前のコマンドを実行できる • これは bash の “HISTORY EXPANSION” と呼ばれる機能 https://www.gnu.org/software/bash/manual/html_node/History- Interaction.html#History-Interaction • なので sudo で実行しろと怒られたら次の様に打てばよい $ sudo !! 直前に実行したコマンドが文字列としてここに入る https://www.thegeekstuff.com/2011/08/bash-history-expansion/