helloworlds

not a noun, it's a verb

【Kali Linux】初期設定メモ

試した環境: version 2018.4

ホストとVirtualboxの仮想環境でのクリップボードの共有

  1. Virtualboxの対象環境を選択し、設定メニューを開く
  2. 一般 -> 高度 タブ -> クリップボードの共有 -> 自分の共有したい方法を選択

f:id:o21o21:20190201141502p:plain:h350:w550

KaliLinuxのTerminalでコピペ

上記の設定を行ってから(ホストのクリップボードの共有しないなら不要)、以下の設定をする。

  1. Terminalを起動
  2. Terminalタブ -> Preferences
  3. 左のメニューShortcuts -> Edit
  4. CopyPasteの項目で、実際入力して設定する

例えば、macならCopy: ⌘command + c にも設定可能

f:id:o21o21:20190201180514p:plain

それでも、効かない場合、Virtualboxの設定を見直す。

ホストキーの組み合わせを、右の⌘commandに設定する。

f:id:o21o21:20190201180354p:plain:h350:w450

再起動

  1. ウィンドウ右上のアイコン(↓)をクリック
  2. 電源マークを押して、Restartで再起動

f:id:o21o21:20190201135935p:plain

デスクトップ画像変更

  1. デスクトップの適当なところで右クリック
  2. Change Background
  3. デスクトップとロック画面を選んで、画像の変更

(デフォルトで何枚かwallpaper用は用意されていました。)

時間の設定

ターミナルで設定する方はこちら↓

 1. 日付時間確認
# date
2. コマンド実行
# dpkg-reconfigure tzdata
3. 設定ウィンドウが展開されるので、`Asia` Enterし、`Tokyo`Enter 
4. 再度dateコマンドで確認
# date
Fri Feb  1 14:07:05 JST 2019

設定UIから設定する方はこちら↓

f:id:o21o21:20190201181259p:plain

日本語&JSキーに対応させる

私の場合、ラップトップは英字なのでキーの操作で困ることはないのですが、 JSキー(日本語配列)の場合、キーの操作で不都合が起こるかと思います。

私は設定してないので、以下の記事を参考にしてみて下さい。

Kali Linux 2018.4 導入と日本語化 | セキュリティ | DoRuby

【TCP/IP】チェックサムを計算していく

今回は、ちょっとした計算をしようかと思います。

ということで、IPチェックサムについて取り上げてみようかと思います。

TCP/IPについて学んでいる時にチェックサムという単語をみかけていて、 その時は読み飛ばしていましたが、気になって仕方がないので記事にしてみました。

ず~~~っと気になっていると、なんだか落ち着かないときってありますよねw

では、さっそくみていきます。

チェックサムとは?

16bitで構成されていて、IPヘッダが壊れていないかをチェックするために存在します。

簡単にいうと、IPプロトコルで通信されている時に、エラーのチェックをする方法といったところでしょう。

ここまでならわかります。

ただ、調べてみると以下のような言葉で説明されているのをよくみます。

チェックサムというのはエラー・チェックの方法の1つで、チェック範囲の値をすべて足し算し、その結果の値と足し算するとすべてのビットが1になるような値を設定します(これを1の補数といいます)。受信した側は、同じ演算を行ってみて、結果が正しくなければエラーが発生したと判断するわけです

引用: パケットを正しく届けるために用意されたIPの機能(第7回) | 日経 xTECH(クロステック)

わたしはここで「どういうこと?」ってなりました。

だって、TCP/IP勉強している最中に言われても、完全に理解しているわけじゃないからよく頭に入ってこなinn...ww

けっこう読み飛ばしてしまう原因なのかと思っておりますw

このチェックサムについて、どうやらなにかを計算するということはわかりました。

「なにを計算するの? どうやって計算するの?」

これを引き続きみていきます。

なにを計算するの?

まず、チェックサムといっても、IPヘッダにもTCPヘッダにも含まれているものです。

IP、TCPUDPにおいて計算方法は同じなので、ここではまとめてチェックサムといいます。

チェックサムの対象は、以下のようになっています。

  • IP -> IPヘッダ部
  • TCP -> データ全体
  • UDP -> データ全体(計算しなくてもよいが、計算することを推奨している)

IPがIPヘッダ部分だけを計算対象とするのは、ルータでIPパケットの分割が行なわれると、 すべてのデータが揃わないので、チェックサムの計算ができなくなるためです。

どうやって計算する?

ここからが頭をよく使って理解していくところです。

さきほども書いたように、どれも計算方法は同じです。

先に具体的な計算方法の解説を書こうと思ったのですが、 先に例として以下の記事(見出し: tcpdumpの出力)でも使用したパケットで計算してみようかと思います。

o21o21.hatenablog.jp

長くなるので、読み飛ばしたい方は、補数とは?を読んで計算方法だけ読んでください。

実際に計算してみる

ここにtcpdumpで出力したパケットがあります。

4500 0034 5125 4000 ff06 0821 0a00 0abb
0a00 03c3 1f36 b702 2e7d 893b 223b 4fd8
8011 00e6 22a4 0000 0101 080a 6aa2 79cb
4b56 71d1

見る限りIPv4のパケットですね。

このパケットの出力から見てみると、IPヘッダとTCPヘッダに含まれる情報が出力されています。

今回は、IPヘッダの計算をしてみようかと思うので、そこだけ抜き出します。

4500 0034 5125 4000 ff06 0821 0a00 0abb
0a00 03c3

チェックサムのフィールドは、0821にあたります。

なので、0821は除外して計算します。

便利な計算サイト(16進数計算機)があるので、一気に足します。

4500 + 0034 + 5125 + 4000 + ff06 + 0a00 + 0abb + 0a00 + 03c3
= 1f7dd

1f7ddと答えが出ました。

これを2進数に変換します。

これも変換サイトがあるので活用します。

2進数に変換すると、11111011111011101になります。これを4bitずつに分けて、16bitの区切りにします。

1 1111 0111 1101 1101

余った今回でいうと1を残りの16bitで区切った2進数と足します。 (計算サイト)

1 + 1111 0111 1101 1101 = 1111011111011110

答えは、1111011111011110になりました。

こちらを4bitずつに区切ります。そして、bitを反転させます。

1111 0111 1101 1110
↓
0000 1000 0010 0001

反転させた2進数(0000 1000 0010 0001)を、16進数に変換します。

すると、821と変換できました。

この821は、計算するときに除外したチェックサムのパケット0821と同等だとわかります。

今回は2進数にしたとき、最初の4bitが0000なので、16進数にしたとき0が抜けていますが、まあ同等です。

と、このようにしてチェックサムを計算できました。

さて、このように計算してきた仕組みをこれから順をおってみていきたいと思います。

補数とは

この記事を書くにあたって、以下の記事を参考させてもらいました。本当にわかりやすく理解しやすかったです。

補数表現とは?1の補数と2の補数の違いと計算方法まとめ | サービス | プロエンジニア

また、これから進数が出てくるの、2進数や16進数についてわからん!という方は、以下の過去記事を参考にしてみてください。

o21o21.hatenablog.jp

補数とは、

ある基数法において、ある自然数 a に足したとき桁が1つ上がる(桁が1つ増える)数のうち最も小さい数をいう。

引用: 補数 - Wikipedia

また、こうして説明されている記事もあったりします。

マイナスがついた数字を、マイナスを使わずに表現する数のこと。

いきなり補数という言葉が出てきました。

実際、数字を使っていった方がわかりやすいと思うのでまず手始めにこんな計算から。

例えば、10の補数で考えてみます。

10の補数で、6と言われたら、4補数になります。

簡単ですね!なんか、お店でお会計するときに1980円だとして、小銭を使おうと2000円と80円出すとお釣りは100円になる、なんかこれに似ていますね。

このレジの例でいくと、10進数で考えて計算しています。

もう少し、砕いていきます。

(※ ここから^を累乗として表します。)

元の桁が1980で4桁です。これは、10^4で、10000です。

10進数の10の補数ということにすると、1980の補数は、8020になるよってかんじです。

# 10進数の10の補数で表現
1980の補数は、8020 : (10^4 = 10000)

このことを、補数といいます。

元の数(1980)と、補数(8020)を足した場合に桁が上がりが発生する数のうち最小の数です。」

そして、補数には、減基数という考え方もあります。

これは、

元の数(1980)と、補数(8020)を足した場合に桁が上がりが発生しない数のうち最大の数が補数になる。」という考え方です。

つまり、1980が元の数ということであれば、8019が補数ということです。

引き算が使えない?

上で、「マイナスを使わずに表現できるのが補数」と書きました。 これはいったいどういうことなのでしょうか。

当たり前といっちゃあ、当たり前なのですが、コンピュータのなかでは0 or 1ですべてが表現されています。

ということは、マイナスなんて使用することはできないのです。

なんか、コンピュータだから引き算くらい当たり前にできるよね!ってかんじのイメージが強いですが、 そんなことはありません。電卓アプリを使っていても、結局内部では0/1で表現されていることになりますからね!

ということで、登場するのがやはり補数ということになります。

補数を使うことはわかったのですが、マイナスを表現するには、どうしたらいいのでしょうか。

また、簡単な計算でイメージを掴みます。

こんな計算があったとします。

1280 - 131 = 1149

そして、以下のように考えます。

# まず、最大桁数1280があって、4桁であると認識します
10 ^ 4 = 10,000

# 131の補数
10000 - 131 = 9869

# 元の1280と、131の補数を足します
1280 + 9869 = 11149

答えは、11149とでました。

そして、先頭の1を取り除きます。すると、1149になりました。 見事、1280 - 131の答えが求まりました。これは常に成り立つ式になります。

ここまでくると、最初にとりあえずやってみたチェックサム計算の仕組みがなんとなーく結びついてきたのではないしょうか!

そして、今やってきたようなことをまとめて、10進数の「10の補数」と「9の補数」という概念でした。(「n進数」の補数)

一般的なのは、2進数の「1の補数」と「2の補数」という概念です。

これからそれををみていきたいと思います。

2進数の「1の補数」と「2の補数」

まず、1の補数からみていきましょう。

1の補数

2進数の1の補数は、減基数をつかった補数です。

なので、n ^ m - 1ということになります。(n進数、元の数の桁数m桁)

さっそく計算していきます。

今回はこの2進数、1001001 をつかって計算していきます。

# 公式にあてはめてみる
2^7 - 1 = 127

# 127を2進数に変換
1111111

# 補数を求める
1111111 - 1001001 = 0110110

求められた2進数は、0110110です。

これを反転(否定という言い方もする?)します。

0110110
↓
1001001

1001001は、元の数ですね!

なんと、実は元の数を反転するだけで、答えを求めることができます。

2の補数

2進数の1の補数の場合は、基数をつかった補数です。 なので、2進数の元の数と補数を足すと、桁上りしまよーということですね。

なので、-1はしないので、n ^ mということになりますね。(n進数、元の数の桁数m桁)

あとは、1の補数のときと同じです。パッとやっていきます。

さっきと同様に2進数、1001001 をつかいますー。

2^7 = 128
10000000 - 1001001 = 0110111

求められた数字は、0110111です。

あれ、これは1の補数のときに求めた数に対して、1を足しただけ?...

1の補数: 0110110

2の補数: 0110111

うん、そうみたいですw

つまり、こちらも簡単に求めるには、元の数を0/1を入れ替える(反転させる)、そして、1を足す

ただそれだけでした。でも、一応計算式を知っていた方が今後応用は効くかと思います。

まとめ

これで大体一番最初にやった計算の意味がつかめたでしょうか。

① 最初にパケットから、IPヘッダの内容を抜き出す

これは、IPヘッダのチェックサムを計算するからですね。

チェックサム以外の16進数を16bitずつ足していく

2進数でも計算できないことはないですが、パケットが16進数なので16進数に頭を変換させます。

③ 2で計算した16進数の答えを2進数に変換します。

④ 16bitを超える(桁上がった)bitと、16bitで区切れた値を足す

16bitずつ足していったので、桁を超える部分は16bitで区切る

⑤ 1の補数にする

4で求めた2進数を反転させます。

⑥ 反転させた2進数を16進数に変換します

もとは、パケット(16進数)だったので、これで最初除外していた値と照らし合わせることができます。

以上.

参考

もっと詳しくチェックサムについて知りたい方は以下のページにアクセスしてみてください。 チェックサムIETFが発行している、技術仕様が日本語訳で載っています。

www5d.biglobe.ne.jp

【TCP/IP】tcpdumpの出力からTCP/IP再入門!

今回は、主にTCP/IPの分野の基礎を固めていければと思い記事にしました。

再入門みたいなかんじです!

本題に入る前に

まず、TCP/IPの説明に入る前に、前提知識として知っておくことがあります。

ネットワーク系の技術書なんかでは当たり前に出てくる2進数や10進数などといった数字の理解についてです。 私自身、プログラムを書く上でそんなに意識して勉強したことがありませんでしたので、 今回は再入門ということで、tcpdump というコマンドを使って、TCP/IPプロトコルなどネットワークの基礎をまとめてみようかと思います。

ただ単に読むだけでは眠くなってしまうので、tcpdumpコマンドで実際確認してみることで、少しでも理解が進むようにしてみますw

(できればEC2とかで動いているWEBアプリとかローカルで開発しているWEBアプリなんかがあるといい..)

「なんか難しそう...」 とか 「数学っぽくて嫌い...」なんて言う方に、よりわかりやすく書いていけばと思うのでよろしくお願いします!w (詳しく説明というよりか、シンプルに要点のみ説明できたらと思います。)

では、さっそく数字の話からしていきます。

進数

ここでは、プログラミング及び、ネットワークを理解していくにあたって最低限必要な 2進数、10進数、16進数 をみていきます。

最初に「どうして進数を知る必要があるの?」ということですが、 まず言えるのが、「この世界において bit で表現されている」ことを認識する必要があります。

bit自体はITに関わっていれば聞いたことはあるかと思います。

では、どうしてbitなのか?ということだが、bit は、コンピュータの中で扱う 最小単位 であることです。

bit は、binary digit の略です。

お、binaryなんてコードを書く人は避けては通れない用語ですね。この bi は、ラテン語bi-が由来です。 例えば、自転車、bicycleという単語があるが、これは 2輪車 のことを示します。2つの ということが大事な点ですね。

つまり、2進数 にもこうした語源から関わってくるのですね〜。なるほどなるほどと。

bitは最小単位であるといいました。コンピュータでは、すべてのデータはbitのonとoffで表現されています。それを数値化することが目的です。

2進数 (binary digit)

2進数 は、数字の 0と1 の2つを使って表現します。

人間がよく表現するならば、10進数を使用しています。(0〜9の10種類の数字を使用していますね。例えば、1,980円でも1と0以外に8と9を使用していますね。)

よく簡単な例として挙げられるのは、電源のonとoffですね。電気の電源とかかな? offが0で、onが1として解釈するのが簡単でいいですね、みたいな。

しかし、コンピュータの中ではそうはいきません。(実際そのonとoffなんだけれども)

23などは2進数でどうやって表現するのでしょう?

2 -> 103 -> 114 -> 1005 -> 101

なんだか規則性がありそうです。そして、桁が増していきそうな気がしますね。

数値が大きくなるにつれて、桁も増すのですがコンピュータの記憶領域に準ずるかたちになります。

つまり、8桁 になります。

言い換えると、1bit を8つ並べた 8bit1byte として扱うことになります。

これは0という1bitで表現可能な数を記憶するにしても、1byte(8bit)を必要することになります。

例を示します。

1001という 2進数 で表現された数字があります。これを 10進数(いつも我々が見慣れている数字)で表現するにはどうしたらいいでしょうか?

2進数から10進数などに変換してくれる便利なサイトがあります。

2進数、8進数、10進数、16進数相互変換ツール

こうしたサイトを利用するのが普段なら便利でいいでしょう。このサイトの2進数の入力フォームに1001と入力すれば、10進数のフォームに9と出てくるので、答えは9だとすぐわかります。

が、一応仕組みというか考え方も学んだ方がいいでしょうw

こちらの表を見てください。

23 22 21 20
1 0 0 1

^は、べき乗、*は、乗算

2進数の1001は、4桁なので、べき乗する数が、0,1,2,3と4つと位が上がっています。 なので、上記の表のように表します。

2^3は、1なので、8 = 1 * 8

2^2は、0なので、0 = 0 * 0

2^1は、0なので、0 = 0 * 0

2^0は、1なので、1 = 1 * 1

ここまでくればわかりましたね。この答えを足すと9になります。なので、1001は、9を表現しています。

そして、これを理解できていれば、2進数から10進数への変換はできることになります。

10進数 (decimal number)

10進数 については、2進数がわかれば特に覚えることはないでしょう。

上記でも記述した通り、 0〜9 の数字で表現するのが10進数です。

人間が理解するのに容易なのが、10進数ですね。

16進数 (hexadecimal number)

これまで数字の0〜9までで表現してきました。

これで十分な気もしますがw、16進数 は、0〜9に加えて アルファベットのA〜F を使用して表現します。

なんかアルファベットって... と、思うかもしれませんが、どういうふうに位が増えていくのかに注目すればなんら難しいことはありません。

以下のように位が増していきます。

0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F

これは、10進数にすると以下のように表現されていることになります。

0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15

0〜9はそのまま表現できますね。そして、A〜Fはそのまま10〜15を表現しています。

そして、16進数なので、16がくるタイミングで桁上りします。なので、16進数において10進数の16を表現するには、10とします。

16進数も2進数で学んだ計算式で考えると理解しやすいかと思います。

161 160
1 0

16^1は、1なので、16 = 1 * 16

16^0は、0なので、0 = 0 * 0

電卓が必要ですが、アルファベットが入っても同様に考えればおk!

163 162 161 160
1 f 3 6

fは、15ですね。

なので、1*4096 + 15*256 + 3*16 + 6*1 = 7990 ということになります。

bit

bit とは、「0 or 1を表す1桁の 」(= 1bit)のこと。

よくあるOS 32bit or 64bit??

単純に考えて、64bit版を選択するのが良いとされる。

  • 32bit = 2x32 = 4,294,967,296
  • 64bit = 2x64 = 18,446,744,073,709,551,616

記憶装置のメモリの制限が設けられているのが主な違いになる。

32bit版は、約3.5GBまでしか使用できないという制限がある。64bit版の方はというと、約128GBまで使用できる。また、ハードディスクの方も同様に制限がある。

TCP

tcpdump

それでは、tcpdump をインストールしてみましょう。

AmazonLinuxであれば、yumでインストールできます。 macはたしか入っていたと思います。そうでなければ、$ brew install tcpdumpとかでやってみてください。

インストールが完了できたら $ tcpdump -hで確認してみましょう。

以下のような出力できたら大丈夫です。

tcpdump version tcpdump version 4.9.2 -- Apple version 83.200.2
libpcap version 1.8.1 -- Apple version 79.200.4
LibreSSL 2.2.7
Usage: tcpdump [-aAbdDefhHIJKlLnNOpqStuUvxX#] [ -B size ] [ -c count ]
        [ -C file_size ] [ -E algo:secret ] [ -F file ] [ -G seconds ]
        [ -i interface ] [ -j tstamptype ] [ -M secret ] [ --number ]
        [ -Q in|out|inout ]
        [ -r file ] [ -s snaplen ] [ --time-stamp-precision precision ]
        [ --immediate-mode ] [ -T type ] [ --version ] [ -V file ]
        [ -w file ] [ -W filecount ] [ -y datalinktype ] [ -z postrotate-command ]
[ -g ] [ -k ] [ -o ] [ -P ] [ -Q met[ --time-zone-offset offset ]
        [ -Z user ] [ expression ]

たくさんオプションがあると思いますが、ここでは一部を扱います。

用途によって(出力したい目的など)、使用するオプションが違うと思います。随時、ググって自分固定のオプションを見つけるといいかもしれませんね!

さて、さっそくコマンドを実行します。

tcpdump コマンドは、スーパーユーザー になる必要があります。

これは、以下の記事でも紹介した通り、プロミス・キャストモード を利用するためです。

スーパーユーザーになる($sudo su -)か、sudoをつけて実行します。

そして、さっきやった進数がさっそく活用できるので、まずコマンドを実行してみます。

$ (sudo ) tcpdump -X

開発しているWebアプリなどがあれば、空いているportを指定してtcpdumpするのが一番良いですが、ローカルでそのまま実行していも構いません。 その代わり、以下のtcpdump出力例にそぐわないパケットを拾ってしまうことが多いので、 推奨はEC2インスタンスtcpdumpをインストールして、稼働しているWEBページにアクセスして出力させるのが好ましいです...

-Xオプションは、パケットの内容を16進数で出力してくれます。

バアーーーっとパケットが出力されたら、Ctr+cで出力をストップします。

tcpdumpの出力

では、出力を見てみましょう。

4500 0034 5125 4000 ff06 0821 0a00 0abb
0a00 03c3 1f36 b702 2e7d 893b 223b 4fd8
8011 00e6 22a4 0000 0101 080a 6aa2 79cb
4b56 71d1

私が実行したときのパケットのかたまりです。みなさんも、値は違えど4文字ずつの同じような文字列が出力されたと思います。

これは16進数で表現されているので、人間でも読み解くことが可能です。

まずは、上記の出力を例に、表にまとめてみました。

項目 bit 説明
バージョン 4 4bit IPv4, IPv6(の場合は"6")
IHL(ヘッダ長) 5 4bit 32bit単位、32x5=160bit=20byte
ToS 00 8bit 優先度
パケット長 0034 16bit 52byte(10進数で)
識別子 5125 16bit フラグメント時に使用されるランダムな値
フラグなど 4000 16bit フラグ,フラグメントオフセット
TTL ff 8bit パケットの寿命64(Linuxデフォルト64)
プロトコル番号 06 8bit TCP=06, UDP=17
チェックサム 0821 16bit IPヘッダーのみ
送信元IP 0a00 0abb 32bit 10.0.10.187
送信先IP 0a00 03c3 32bit 10.0.3.195
送信元port 1f36 16bit 7990 (10進数で)
送信先port b702 16bit 46850 (10進数で)
シーケンス番号 2e7d 893b 32bit
ACK番号 223b 4fd8 32bit
データオフセット 8 4bit 32bit単位、32bitx8=256bit=32byte
コントロールビット 011 12bit ACK/FIN (予約領域を含む: 内コントロールフラグ6bit)
ウィンドウサイズ 00e6 16bit 230 (10進数で)
チェックサム 22a4 16bit 疑似ヘッダー含むチェックサム
緊急ポインタ 0000 16bit
オプション(NOP) 0101 080a 可変
タイムスタンプ(TSval) 6aa2 79cb 16bit
タイムスタンプ(TSecr) 4b56 71d1 16bit

16進数ですので、10進数の変換するとport番号などが隠れていることがわかります。

たくさんの項目がありますが、順をおってみていきます。

IPv4IPv6(バージョン)

今回は、4と出力されています。

この4は、IPv4 を示しています。

IPv4 は、32bit で構成されているので、232で約43億個のアドレスを保有しているよーってことになります。

IPv6 は、128bit で構成されているので、2128で約340澗(かん)個のアドレスを保有しているよーってことになります。

桁が違うので、IPv6は世界の人々、一人一人に割り当てたとしても0.00000001%くらいにしかならないのです。 ほぼ無限に近い(無限に近いって言い方もへんだけど)数ですw

ここで、重要なのは表記についてです。

IPv4 IPv6
表記例 192.168.0.1 2001:0db8:1234:0088:90ab:cdef:0000:0000
bit 32bitを8bitずつ4つのフィールドになる 128bitを16bitずつにして、": (コロン)"で区切って8つのフィールドになる

パッと見、IPv6の方は抵抗がある方もいるかもしれませんが、ここでは進数について勉強したので大丈夫でしょう。 なんら考え方は変わりません。

にしても、IPv6は長い...

ということで、省略表記も存在します。上記の例から省略すると、

2001:db8:1234:88:90ab:cdef::

みたいになります。

特に難しいことはなく、各フィールドの0始まりなら0を省略できることと、0が連続している場合、:に省略できることくらいわかっていれば大体問題ないでしょう。::は1つのIPに1度だけです。

そして、もう1つ重要なのは 構成 です。

ネットワーク部とホスト部

IPv4 は、ネットワーク部ホスト部 によって構成されています。

こんなかんじです。

f:id:o21o21:20190129171601p:plain

この例では、ネットワーク部とホスト部の区切りが2つあるのですが、これは、IPアドレスによって 異なります

ネットワーク部 は、どのネットワークに所属しているかを示します。

ホスト部 は、そのネットワーク内のどのホスト(端末)なのかを示しています。

でも、どこから区切りになるのか、どうやって決まるのでしょうか?

それは、クラスフルアドレスクラスレスアドレス によって区別されることになります。

ただし、主流なのは クラスレスアドレス で、サブネットマスク によって区別されていると知っておけばよいでしょう。

サブネットマスク は、IPアドレスとセットで使用される。

イメージとしては、1つの大きなネットワークを小さいネットワークの集合体に分割したものとして覚えるといいかもしれません。

表記は、IPアドレスと変わらなく、255.255.255.0 のようなかんじになっている。表現の仕方は以下を参考にしてください。

# IP (192.168.0.1)の2進数表記
11000000.10101000.00000000.00000001

# サブネットマスク (255.255.255.0)の2進数表記
11111111.11111111.11111111.00000000

# IP (192.168.0.1)のネットワーク部
11000000.10101000.00000000

# IP (192.168.0.1)のホスト部
00000001

つまり、サブネットマスク11111111が並んでいるところがネットワーク部、ということですね。(このネットワークに属していますよ。)

サブネットマスクで表記することもできますが、CIDR表記 といってもう少し短くネットワーク部とホスト部を簡単に区別して表記する方法もあります。

192.168.0.1/24 と表記します。

これは、先頭から3つ(24bit)をネットワーク部とします、という書き方です。 なので、192.168.0.1/24 = 192.168.0.1 255.255.255.0は同様です。

さて、覚えることが多くなってきましたが、これは IPv4 の構成です。

次は、IPv6 について見てきます。

プレフィックスインターフェイスID

IPv6 は、プレフィックスインターフェイスID で構成されています。

IPv4は32bitでしたが、IPv6は128bitですね。

なので、プレフィックスインターフェイスID に何bitずつか割り当てられることになります。

プレフィックスに64bit、インターフェイスIDに64bitで、プレフィックス(ネットワーク部)が十分なためネットワーク部分のアドレスが変更されることは少ないでしょう。

2001:0db8:1234:0088:90ab:cdef:0000:0000

上記の例でいくと、2001:0db8:1234:0088ここの部分が64bit(1フィールド16bit)でプレフィックスになりますね。

また、同様に2001:0db8:1234:0088/64として、CIDR表記にしても大丈夫です。

こうしてIPアドレスの表記などについて見ていきましたが、どうしてこうしたことを知る必要があるのかというと、 ネットワークの作成などで役立つ知識となります。また、社内ネットワークなんかもこうしたIPの範囲で構成されていることになります。

まあ、大概IPv4で構成されているネットワークが現在多いのですが、ここではIPv6でイメージしてみます。

例えば、2001:0db8:1234::/48と書かれたネットワークが存在するとします。

これだと2^80個のアドレスを含む。(ちなみにIPv6においての推奨される割当の大きさは/48)

2001:0db8:1234:0001::/64
2001:0db8:1234:0002::/64
2001:0db8:1234:0003::/64
2001:0db8:1234:0004::/64
.
.
.
2001:0db8:1234:ffff::/64

となり、2001:0db8:1234:0000:0000:0000:0000:0000 〜 2001:0db8:1234:ffff:ffff:ffff:ffff:ffffの範囲である。

ちなみに数値すると1,208,925,819,614,629,174,706,176個の範囲を示すことができる。

社内ネットワークで考えてみて、社員人数分のIPが必要で、辞める社員がいたとしても、何世紀もつかわからんレベルの範囲であるw

IPv4で考えてみる。

192.168.0.0/24だとすると、192.168.0.0 〜 192.168.0.255になるので、IPの個数は256個となる。

うん、これなら現実的かな。むしろ大規模の会社では足りないですね。 だからこの部署は、こうして192.168.1.0/24、この部署は、192.168.2.0/24こうするか....みたいなかんじです。 なんとなくイメージはついてたでしょうか?

長くなりましたが、最初は重要な基礎が多いので、説明が長くなりますが、引き続きtcpdumpの出力から学んでいきます!w

ヘッダ長

tcpdumpの出力によると5が出力されています。

32bit単位で計算するので、5x32bit=160bit=20byteとなります。

この20byteはなにを意味しているのでしょうか。

理解するために、基礎知識がまた必要なので説明していきます。 長くなりますが、ご了承ください!ww

プロトコル

さて、どうしてプロトコルが出てくるのかということなのですが、 ここでは、「そもそも通信機器がどうやって互いにデータを送り合ったりできるのか?」ということを理解する必要があるためです。

プロトコル(Protocol) とは、機器同士が通信を行うための 手順や規格 ことです。

主に 約束事 として紹介されていると思います。

辞書には、議定書や原案、儀礼などとして載っています。

簡単にいうとデータを送受信するための端末情報、データの形式、パケットの構成、エラーだった場合の対処法などが詰まっているわけです。

プロトコル は複数存在します。基本的に一般の方はプロトコルを意識して生活するということはないでしょう。

プロトコルはアナログ通信にも存在するようです。プロトコルだからといって、なんでもランダムに使用されているわけではなさそうですね。

プロトコルの階層化

基本的な概念がプロトコルには存在します。

1980年に発表された OSI参照プロトコル というものです。

そして、このモデルに基づいてコンピュータ間の通信などにおいて使用されるプロトコルは1つではなく、それぞれ役割があって複数のプロトコルが使用されることになります。 OSI参照モデルを元にして 7つ の階層に分かれている構造のことを プロトコルスタック といいます。

色んなプロトコル

f:id:o21o21:20190129171721p:plain

このように7つのレイヤーに分かれていて、各レイヤーに色んなプロトコルが存在します。

よく聞く TCP/IP(プロトコル) とは一体どこのレイヤーに位置するのでしょうか?

実は、TCP/IPOSIモデルに沿っていないのです。 沿ってないというよりは、ネットワークの技術が普及するにつれて、そこまで「詳細に階層分けしなくなった」という方があってるかもしれません。

TCP/IPは、4階層 にわかれています。

f:id:o21o21:20190129171743p:plain

  • アプリケーション層

ここでの規定は、各アプリに依存する。 HTTP,SMTP,FTP,SSH,POP3...

ここでは、TCPUDPプロトコルが使用される。 ネットワーク内で接続されている機器(ノード間)のデータ転送の信頼性を確保する。 TCP, UDP

  • インターネット層

IPが代表的なプロトコルEnd2End の通信を実行するための規定。 IP, ARP, ICMP...

直接的に接続された機器(ノード)間の通信のための規定。 詳しくは、こちらEthernet, PPP...

各レイヤーの規定をみてくると、通信の順番がわかるかと思います。

送信する側は、アプリケーション層から始まりネットワークインターフェイス層でカプセル化を行い データを流します。

受信側はこの逆で、ネットワークインターフェイス層 -> アプリケーション層の カプセル化 を行ってデータを取り除いていきます。

自宅の環境を考えてみると簡単です。

自宅でスマホをいじっています -> 何かアプリで友人にメッセを送信します ->

自宅のWi-Fiを経由します -> たくさんのサーバーや基地局を経由します ->

宛先の機器のWi-Fiまで到達します -> 友人のスマホに到達します

ざっくりですがこんな流れでしょうか。

ゲームなんかのリアルタイム処理が重要な通信においては、ルーターの性能や機器の処理速度が重要になってくるのもこれを考えればなんとなく理解できるかと思います。

実際は開発者の匠の技がいくつも隠されているのですw

かるくネットワークについて

こうした通信(TCP/IP)は、巨大なネットワーク、インターネット (Internet) で行われていると理解することが大事です。

なんかインターネットって当たり前の技術みたいに思われがちですが、あくまで地球規模のネットワーク という風に認識することが重要です。

そして、上記で1例としてあげた「TCP/IPというプロトコルが使用されているよ」ということですね。

他にもネットワークと呼ばれるものはあります。

会社では、イントラネット (intranet) というネットワークです。

「あれ?会社でもYahoo開いてるし、ネット使ってるからインターネット環境じゃないの?」と思われる方もいるかもしれませんが、正確には呼び方が違います。

特定範囲(会社や学校など) のコンピュータを繋いで構成されているネットワークは、イントラネットと呼びます。おそらく大企業さんであれば、情シスの方?が管理されているのでしょうか?(大企業に入ったことないからわからないw)

これは、LAN という仕組みを応用したものになります。同じ建物など物理的に隣接している場所で、機器を同士をつないでネットワークを構成します。この時、無線やケーブルで機器同士をつないでると思います。

また、WAN という都市や国などもっと大きな枠組みで、離れた場所をつなぐ仕組みがあります。

WANは、光ケーブルなどを使用してネットワークを形成しています。

ヘッダ長にもどりますw

それはそうと、もとはなんの説明をしているかといえば、ヘッダ長ですねwww

ここまできて ヘッダ長 を理解できますw で、実はもうほとんど理解したようなもんです。

ヘッダ長とは、インターネット層で付けられたヘッダ (IPヘッダ) です。

以下の図も見てください。

f:id:o21o21:20190129171823p:plain

パケットの交換 といって、大きなデータを パケット(Packet) に分割して送信しています。

その時、通信するコンピュータは、プロトコルに従って、ヘッダを作成したり、ヘッダの内部を解読して処理したりしています。

高級なプロトコル(ここではTCP)は、低級なプロトコル(ここではIP)によって取り込まれていくイメージです。 TCPプロトコルは、IPプロトコルペイロードに属しているようなかんじです。

IPヘッダの長さは、5ですよ、というふうに出力されています。

単位は32bit、または4byteで、それぞれ、

  • 5 * 32bit = 160bit
  • 5 * 4byte = 20byte

このようになり、数値は一緒になりますね。

そして、この20byteは、以下のような内容が含まれている。(引用)

  0                   1                   2                   3
  0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |Version|  IHL  |Type of Service|          Total Length         |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |         Identification        |Flags|      Fragment Offset    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |  Time to Live |    Protocol   |         Header Checksum       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                       Source Address                          |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Destination Address                        |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                    Options                    |    Padding    |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
 |                        data(ip payload)                       |
 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

IPヘッダのフォーマットとして、IPヘッダIPペイロード になるが、送るデータがない限りの最小サイズは20byteということになる。

ToS,パケット長,識別子,フラグ,TTL,プロトコル番号,チェックサム,送信元IP,送信先IP

さて、上記のIPのヘッダの中身を見てみましたが、tcpdumpの出力の項目は上記の表に当てはまることがわかります。

IPヘッダには、送信先IP以降は載っていないように見えます。

送信先portからの出力は、TCPヘッダ の中身になります。

以下も参考にしてみてください。(引用)

0                   1                   2                   3   
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                        Sequence Number                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Acknowledgment Number                      |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|  Data |           |U|A|P|R|S|F|                               |
| Offset| Reserved  |R|C|S|S|Y|I|            Window             |
|       |           |G|K|H|T|N|N|                               |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|           Checksum            |         Urgent Pointer        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                    Options                    |    Padding    |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                             data(tcp payload)                 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

TCPパケットもIPパケットのフォーマットに似ています。

TCPヘッダTCPペイロード にわかれています。

TCPペイロードTCPより高級のプロトコルを含むデータということです。

重要そうな項目をみていきます。

細かい項目の意味については、こちら(IP, TCP)を参考にしてみてください。

ToS (Type of Service)

送信しているIPのサービス品質を示しています。

現状、インターネットではあまり利用されていないそうです。

パケット長

IPヘッダIPペイロード を加えたパケット全体の長さを示します。

識別子

フラグメント(パケットの分割化処理)を復元する際の識別子。

フラグとフラグメントオフセット

  • フラグ

3bitで構成されていて、パケットの分割に関する制御を指示します。

  • フラグメントオフセット

13bitで構成されていて、分割されたフラグメントが、どこに位置していたのかを示します。

TTL (Time To Live)

もともとは、このパケットがネットワークに存在してよい時間(秒単位)を示していましたが、 実際のインターネットでは、いくつのルーターを中継してもよいか、という意味になります。

プロトコル番号

IPヘッダの次のプロトコルが何であるか を示します。

チェックサム

IPヘッダのチェックサムを示す。 詳しくは、こちらを参考。

送信元IP, 送信先IP

送信元・送信先IPアドレスを示します。

送信元port, 送信先port

送信元・送信先のポート番号(Port)を示します。

シーケンス番号

シーケンス番号。

シーケンス番号は、送信したデータの位置ということ。

ACK番号 (Acknowledgment Number) 確認応答番号

確認応答番号は、次に受信すべきデータのシーケンス番号になっています。

データオフセット (Data Offset)

TCPが運んでいるデータがTCPパケットの先頭のどこから始まるのかを意味しています。

つまり、TCPヘッダ の長さを示しているということになります。

コントロールビット(または、コントロールフラグ) と 予約(Reserved)

コントロールフラグ は、8bit長で、以下のフラグが存在する。

  • CWR
  • ECE
  • URG
  • ACK
  • PSH
  • RST
  • SYN
  • FIN

全ては紹介しませんが、代表的な 3way Hand Shake (3ウェイハンドシェイク) を紹介します。

3way Hand Shake (3ウェイハンドシェイク)

TCPで通信する際に利用されるやり取りです。

名前の通り、3回のやり取りを経て接続を確立する方法になります。 クライアントと対象のサーバーとのやり取りを例にしてみます。

順番はシンプルにこんなかんじです。 

f:id:o21o21:20190129171858p:plain

SYN は、コネクションの確立 に使われます。 1になっているときは、コネクションが確立されていることを示します。さらに、シーケンス番号(Seq)が初期化されます。

ACK は、1の時、確認応答番号(ACK番号)のフィールドが有効なことを意味します。

ここでは出てきませんが、FIN というフラグもあります。 これは、コネクションを切断したという意味を示します(1のとき)。

ウィンドウサイズ

TCPヘッダに含まれる確認応答番号で示した位置から、受信可能なデータサイズを通知するのに使われます。

チェックサム

TCPチェックサム

緊急ポインタ

コントロールフラグのURGが1の場合に有効になります。 ここの数値は、緊急を要するデータの格納場所を示すポインタとして扱わられます。

オプション

TCPによる通信の性能を向上させるために利用されます。

詳しくは、こちらを参考にしてみてください。

まとめ

tcpdumpは随時実行してみてください! 目的や欲しいキャプチャによってオプションは変わってくるので、自分で使いやすいようなオプションを見つけられるといいです。

まだまだ基礎については書き足らないところがたくさんあります...

次は、有名な本「マスタリング TCP/IP」でも読んでみてまとめてみようかと思います。 もちろんすべては無理なので、私が重要だと思うメモみたいになってしまうかもしれません...

以上.

参考&引用

【outguess】画像ファイルに秘密ファイルを埋め込む!?

今回はステガノグラフィ・ツールで遊んでみます!

ステガノグラフィ・ツールとは、音声や画像などのデータに秘密のメッセージを埋め込む技術のことです。

ちょっとワクワクしますね!w

一見普通の画像ファイルに見えるのですが、秘密の情報を埋め込んであり、誰かに渡すといったことも可能です!

受け取った方は、秘密のワードで、その秘密ファイルを取り出すといったことを想定します。

私の環境はmac(OS X)です。

この記事では、outguessというツールを使用します。

macではoutguessがGUIになっているので、仮想環境を作成します。

仮想環境には、VirtualBoxを使用してUbuntuvagrantを使用します。 この記事では、細かいインストール手順は説明しませんが、大体は書いてあるので良かったら参考にしてください。

(vagrant upあたりからエラーやらWARNINGが出る方もいるかと思いますが、随時ググってください。たくさん有益な対処法が見つかると思います。)

では、さっそくやっていきます。

VirtualBox

以下からOSにあったVirtualBoxをダウンロードします。

www.virtualbox.org

Vagrant

Vagrantも以下からダウンロードします。 特にこだわりがなければ最新のヴァージョンでいいと思います。

www.vagrantup.com

準備

仮想環境を作成するので、作業ディレクトリをつくります。 あとからヴァージョンの違ったboxを追加したりすることを想定して、以下ののようなディレクトリを任意の場所で作成します。 (ここでは以下の名前で作成してますが、ディレクトリの名前はなんでも構いません。)

~/VirtualEnv/ubuntu/1604/

VagrantBox

VagrantBoxをインストールします。

A list of base boxes for Vagrant - Vagrantbox.es

上記のサイトからインストールできる一覧が記載されています。

今回は、ubuntuを選択できれば良いので適当なboxを見つけて以下のコマンドを作成します。

$ vagrant box add ubuntu16.04 https://cloud-images.ubuntu.com/xenial/current/xenial-server-cloudimg-amd64-vagrant.box

このコマンドは、vagrant box add < 任意のBox名前> <Boxがあるパス> という構成です。任意のBox名前は、後から自分でわかりやすいような名前がいいかと思います。今回はヴァージョンを名前にいれていますが、プロジェクト名とかでもいいですね。

そしたら上記のコマンドを実行します。(このコマンドの実行はどこのディレクトリでも構いません。)

少し時間がかかるかもしれません。できるだけネットワーク環境の良いところでインストールするのがオススメです。

Vagrantfile

インストールの完了が確認できたら、さきほど作成した作業ディレクトリに移動します。

移動したら、まずworkというディレクトリを作成しましょう。($ mkdir work)

そして、以下のコマンドを実行します。

このコマンドは、さきほどインストールしたBoxファイルを展開するイメージです。

initすると、Vagrantfileというファイルが作成されます。

$ vagrant init ubuntu16.04

A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

initが完了したらVagrantfileを編集します。

vimでファイルを開いて、config.vm.network "private_network", ip: と書いてある行を探し、コメントを外します。

次に、config.vm.synced_folderを書いてある行を探し、コメントを外して、共有フォルダを設定します。

config.vm.synced_folder "ホスト側のパス", "ゲスト側のパス"

今回は、config.vm.synced_folder "./work", "/home/vagrant/work" このように設定しました。

./workは、Vagrantfileと同じ階層にあることになります。 ホストOSで秘密のパスワードを展開する際に、共有していると便利です。

これでようやく仮想環境を立ち上げることができます。

以下のコマンドをVagrantfileがあるディレクトで実行します。

実行したら稼働しているか、確認します。

# 仮想環境を立ち上げる
$ vagrant up

# 仮想環境が稼働しているか確認
$ vagrant status

# (仮想環境内)仮想環境をぬける
$ exit

確認ができたら、仮想環境に入ります。

$ vagrant ssh

入れましたか? おそらくvagrantユーザーになって、ubuntuを操作することが可能なはずです!

apt-get

さあ、ここからが本番です。

ubuntuでは、apt-getでパッケージをインストールするのが常だと思います。

なので、まずはアップデートしてから、outguessをインストールしてみましょう。

$ sudo apt-get update
$ sudo apt-get install outguess

もしユーザーを変更したかったり、outguess専用のユーザー作成したかったら以下を参考にしてみてください。

Ubuntuでユーザーの確認・追加・削除・sudoに追加 - Qiita

outguessのインストールが終わったら、確認してみましょう。 以下のような出力があれば大丈夫です。

$ outguess

OutGuess 0.2 Universal Stego (c) 1999-2001 Niels Provos

outguess [options] [<input file> [<output file>]]
    -[sS] <n>    iteration start, capital letter for 2nd dataset
    -[iI] <n>    iteration limit
    -[kK] <key>  key
    -[dD] <name> filename of dataset
    -[eE]        use error correcting encoding
    -p <param>   parameter passed to destination data handler
    -r           retrieve message from data
    -x <n>       number of key derivations to be tried
    -m           mark pixels that have been modified
    -t           collect statistic information
    -F[+-]       turns statistical steganalysis foiling on/off.
                 The default is on.

ubuntuで準備

ubuntuでも作業ディレクトリを作成しましょう。

/home/vagrant/work/outguess/

作業ディレクトリに移動したら、次に画像が必要です。

画像

著作権フリーのサイトからcurlでダウンロードします。

$ curl -o woods.jpg https://cdn.pixabay.com/photo/2018/11/23/14/19/forest-3833973_1280.jpg

今回はwoods.jpgという名前でダウンロードしました。

テキストファイル

パスワードが書いてあるtxtファイルを作成し、1行目にパスワードを記述して保存します。 (今回はテストなので、適当に単語を記述しました!)

$ vim pwd.txt
〜 編集 & 保存〜

作成

さあ、ここでようやく情報を隠した画像ファイルを生成します。

-kオプションは、提供されたデータ内のメッセージを暗号化して隠すために使用されます。

その他コマンドのオプションはこちらにあります。

コマンドは以下の通りです。

# コマンド
$ outguess -k <secret_key_word> -d <text_file> <pics_file_name> <new_pics_file_name>

# コマンド例 (今回)
$ outguess -k oolongtea -d pwd.txt woods.jpg beautiful-woods.jpg

実行してみると、beautiful-woods.jpgが作成されたかと思います。

取り出し

さあ、ホスト側のFInderかなんかでubuntuとマウントされているディレクトリを見てみましょう。

f:id:o21o21:20190124144918p:plain

うん、普通の画像ファイルが存在していますね!

ここからubuntuで指定した秘密の文章(pwd.txt)を取り出します。

macでは、outguessはGUIとして存在します。

なので、ダウンロードします。

$ brew install outguess

インストールしたら、アプリケーションフォルダにあるoutguessを起動させます。

そうするとこんなのが立ち上がるかと思います。

f:id:o21o21:20190124145152p:plain

上のメニューで、Extractという項目があるので押下。

そうすると、FromKeyが入力できます。

Fromの方で、ubuntuのoutguessで生成した画像ファイルbeautiful-woods.jpgを指定。

Keyでは、oolongteaを入力して、*Extractボタンを押します。

取り出されたファイルを格納するパスを聞かれるので、適当にしてします。

そのファイルを見てみると.........

ubuntuで作成した秘密の文章ファイルがちゃんと記載されています!!!

これで、終了です。

まとめ

今回はoutguessについてでした。

ホスト側とゲスト側での、一人でできるハンズオンでしたが、 友人や同僚とやってみるのも面白いかもしれません。

これで何気ない画像に秘密の情報を埋め込み、取り出す方法を実感できたと思います!

以上.

【インフラ】気になるLinuxコマンド!

今回はLinuxのコマンドについて色々調べてみました。

自分の場合、仕事でもプライベートでもだいたい同じコマンドを使っていますが、 作業中に「もっと便利にならないかな?」とか効率化を求めます。

が、その時は思っていてもすぐ忘れていて、新しいコマンドを一時的にしか覚えられない....

ということで、サーバーサイド、インフラエンジニアがよく使うコマンド!みたいなかんじで調べてまとめようかと思います。 (完全あとで見直す用になりそうw そして、随時更新していきます ############)

コマンドって一体どれくらいあるの??

一度は考えてしまうと思いますw 一体この世の中には何種類のコマンドが存在するのか?

この疑問を解決するには、まず種類分けをしなければならなそうです。 例えば、UNIX系なのか、とかとか... ちょっと調べましたが中々統計データは出てこなかったのでわかりませんでした。

これはLinuxで使用されるコマンド集。

fossbytes.com

これだけでも膨大な量ですねw また、AWScliとかWindowsコマンドとかたくさんあるので、調べようがない... 日本人の方でコマンド集を随時更新されている方がいましたが、そこではコマンドの種類問わず、約500のコマンドが記載されていました。

なので、ここでは主にLinuxで用意されているコマンドをみていきます。

また、"どうしてコマンドが使用できるのか"など、その仕組については割愛します。 以下の記事がわかりやすいので、載せておきます。

シェルの概念と機能

もしなんの種類のシェルを使用しているのかわからない方は以下を実行してみましょう!

$ echo $SHELL

基礎

ps

Linux上で動作しているプロセス (process)を確認するコマンド。 コマンドの話ではないですが、私なんかは自宅のWindowsデスクトップを使用しているとき、 セカンドディスプレイで必ずタスクマネージャーを表示させています。 GUIがなくてももちろんプロセスは確認しないといけませんね!

これでプロセスを確認。(オプションなしでも使用できる)

$ ps
$ ps auxwwf 
$ ps rlu
$ ps auxwwrlue
オプション 内容
-A 全プロセスを表示する。
a 端末操作のプロセスを表示
x 端末操作以外のプロセスを表示
r 現在、実行しているプロセスを表示
c 実行しているコマンド名を表示
e 実行しているコマンド名と環境変数を表示
u CPUやメモリの使用率なども表示
h 項目名を表示しない
l プロセスの状態なども表示
f プロセスを階層で表示
o 指定したリスト順の出力形式で表示
-C 実行しているプロセスやプログラムのファイル名を指定
-u プロセスを実行しているユーザーを指定
-g プロセスを実行しているグループを指定
-p 実行しているプロセスのプロセス番号(PID)を指定
--sort プロセスの表示順を指定
w 出力時の幅を広げる

よく使用されるオプションとして、fがあるようだけど、なんとmacでは使用できない。 オプションfは、プロセスを階層で表示するためのオプション。 そのかわりに、pstree コマンドが使用できるようです。

$ brew install pstree
$ pstree

pstreeをオプションなしで実行すると、ものすごい勢いでツリーが表示されてしまいますw なので、パイプをあわせて使用したほうが良さそうです。

$ pstree | grep root

どうしてツリー表示がいいかというと、子プロセスをkillしても問題が解決しない場合があって、親のプロセスをおう必要があるからです。

psコマンドはここまでにして、リアルタイムでプロセスを確認する手段もあります。

top

topコマンドは、実行中プロセスの情報をリアルタイムで確認できるコマンドです。

オプションなしで実行できます。

$ top
$ top -u <user_name> # ユーザーを指定
$ top -p <process_id> # プロセスIDはを指定
$ top -d 1 # 表示間隔を1秒にする

少しだけ覚えることがあります。 プロセスが表示されている時に操作することができるので、その操作を知っておくと便利かもしれません。

キー 内容
k 指定したPIDを終了する
r 指定したPIDのNIを変更する
l, t, m 画面上部に表示されている情報の表示/非表示を切り替え
z 画面上の文字に色をつけて強調表示
Shift+V プロセスの一覧をツリー状に表示
Shift+P プロセスの一覧をCPUの使用率が高い順に並べ替え
Shift+M プロセスの一覧をメモリの使用率が高い順に並べ替え
Shift+T プロセスの一覧を稼働時間が長い順に並べ替え

NI(ナイス値)とは、プロセスの優先度を示す数値のこと。-20〜+20で、-20が最も高い優先度になる。

macの場合操作がうまくいかないことがありました。 その場合は(例: CPU使用率順)、top -o cpuでtopコマンドを実行するか、 起動後、o > cpu > Enterでソートできました。 ちなみに、AmazonLinuxでは上記の表で操作できました。

あくまで私の場合ですが、macbook Pro(Core i7, メモリ16GB)で随時起動させていて、他のアプリが重くなるなどの事象は起きないくらいです。 そして、気づいたですが、表示されているプロセスの件数は、画面の大きさに依存するようです。スクロールできないので、たくさん表示させる必要がある場合はウィンドウを広げたほうが良さそうです。

vmstat (vm_stat)

topコマンドがあるのに、vmstatを使用する場合とはどういうことなのでしょうか。 vmstatは、主に仮想メモリやCPU、ディスクI/Oの情報などを確認します。私の理解が正しければ、I/Oに注目すると良いかもしれません。

このコマンドはオプションの使用で、最短1秒での情報を随時確認できます。

$ vmstat
$ vmstat 1       # 1秒間隔で表示 (1行目は、最後に起動した時からvmstatコマンド実行開始までの統計情報を表示)
$ vmstat 1 10  # 1秒間隔で10回表示 
# 出力例

procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 0  0      0 1015184 695248 754740    0    0     0   206    0    1  8  2 90  0  0   
 0  0      0 1015292 695248 754740    0    0     0     0   48   44  0  0 100  0  0  
 0  0      0 1015292 695248 754740    0    0     0     0   31   38  0  0 100  0  0  
内容
procs r 実行中と実行待ち中のプロセス数合計
b 割り込み不可能なsleep状態にあるプロセス数
memory swpd 使用中の仮想メモリの量
free 空きメモリの量
buff バッファとして使用しているメモリの量
cache cacheに使用している量
inact アクティブではないメモリの量
active アクティブなメモリの量
swap si ディスクからスワップインしているメモリの量
so スワップアウトしている量
io bi HDDのようなブロック型デバイスから受け取ったブロック数
bo ブロック型デバイスに送ったブロック数
system in 1秒当たりの割り込み回数
cs コンテクストスイッチの回数
cpu us カーネルコード以外の実行に使用した時間(プログラムが動いていた時間)
sy カーネルコードの実行に使用した時間
id 空転していたアイドル時間
wa I/O待ち時間
st ゲストOSがリソース要求を行い、CPUリソースを割り当てがなかった時間の割合

r(実行中/実行待ち)の値がずーっとある場合処理が追いついていないなどが考えられる。 それと同時にswapのsi/soも確認する。できるだけここの値は0になることが好ましい。

このコマンドも運用で頻繁に使用していることが好ましいかもしれない。項目をみれば理解できるが、アプリエンジニアがちょっと見ただけでは、サーバーのスペックだったり、負荷のかかる時間帯だったり、色々とタイミングがあるので、ちょっとずつ観察していくのが良いかもしれない。

I/Oについてはこちらに詳しく載っているので、あとで確認してみるといいかもしれない。

netstat

netstat(Network statistics)とは、ネットワーク接続やルーティングの状況などの状態を出力します。

TCPおよびUDPプロトコルを対象に統計情報を出力するので、ネットワーク系、例えばLISTENしているportの確認や、 意図しない通信をしていないかなどを確認することができます。 インフラの構築のときなど、どのportが待ち受けているかなど便利かもしれません。

$ netstat -lt    # TCPプロトコルで、LISTEN中(待ち受け中)のソケットを確認
$ netstat -an | grep LISTEN  # アクティブなソケットでホストやユーザーの名前解決せずそのまま表示してgrepに渡す

| | 内容 | |-A |接続状態を表示するアドレスファミリを指定| |-I |指定したNICの情報のみ表示(ex. -Ieth0)| |-a| 全てのアクティブなソケットを表示| |-c| 1秒ごとに更新しつつ表示| |-e| 詳細情報を表示| |-g | IPv4IPv6マルチキャストグループメンバーシップ情報を表示| |-i |全てのNICの状態テーブルを表示| |-l |接続待ち(LISTEN)状態にあるソケットのみ表示| |-n| ホストやユーザーの名前解決を行わず数字のまま出力| |-o| ネットワーキングタイマーの情報を出力| |-p| ソケットが属すプログラムのPIDとプロセス名を表示| |-r| ルーティングテーブルを表示| |-s| 各プロトコルの統計情報を表示| |-t| TCPソケットを表示| |-u| UDPソケットを表示| |-v| 詳細な情報を表示|

tcpdump

tcpdumpとは、ネットワークインターフェースを通るパケットのヘッダ情報を出力するコマンドです。

AmazonLinux1にはデフォルトでインストールされていなかったので、yum install tcpdumpですぐインストールできます。

このコマンドは、ネットワーク機器の間の通信内容を取得し、正常なパケットが送受信されているかどうかを確認します。リバースプロキシの設定をしていて、ぶら下がっているサーバー(ソフトインストール前とか)に対して、本当に通信されているかどうかなども確認できます。笑

ネットワークトラフィックをダンプする。膨大に流れているパケットを適切にフィルターして使用する必要がある。 Wikipediaで紹介されている言い方だと、計算機ネットワーク調査ツールと呼ばれるものの一種である。 Windowsには、Windumpというコマンドが用意されていて、Windows上でtcpdumpを動かせるようにしたもの。 基本的にスーパーユーザーになる必要がある。理由として、プロミス・キャストモードを利用するためである。

  • プロミス キャストモードとは

プロミスとは「無差別の」という意味で、自分宛のパケットでない信号も取り込んで処理するということを示す。 主な使用目的としては、適切なルーティングがなされているか、デバッグなどである

オプションが多いので、ぜひこちらの表を参考にしてみてください。

【tcpdump】ネットワークトラフィックをダンプ出力する | 日経 xTECH(クロステック)

ここでは、使えそうなオプションで例を書いてみます。

# インターフェイスを指定して
$ tcpdump -i eth0

# ホストを指定
$ tcpdump host <IP/Host_name>

# (Hostと)ポート番号を指定して
$ tcpdump port 8080
$ tcpdump host 192.168.0.1 and(or) port 80

# 発信(dst)/受信(src)で絞る
$ tcpdump dst port 80
$ tcpdump src port 80

その他、こちらの記事を参考にしてみてください。

参考

【tmux】tmux入門 (mac)

今回はtmuxについて記事を書きました。

私的なことを言うと、最近インフラよりの知見を貯めているからです!w

それはそうと、以前からtmuxについては、名前くらいしか知りませんでした。 (というか、この記事を書いているときもtmux歴まだ1ヶ月も経たないくらいです...w)

なので、入門として読んでくださると助かります!

「これからtmux使ってみよう!」

とか、

「基本設定ってどんなかんじになるうだ?」 など、疑問に思っている方向けになります。

では、さっそく基本情報から見ていきます。

※筆者のOSは、OS Xです。

概要

tmuxとは?と、まず思うことでしょう。何ができるのか?などなど...

tmuxとは、 ターミナルマルチプレクサです。 (※できるだけ個人の解釈でなく、公式の文を引用します。)

マルチプレクサとは、簡単に言うと、複数の信号を1つの信号として出力することです。 これは電子回路系のお話なので、もっとわかりやすくいうと、1つのコンソールで複数のコンソールを仮想的に展開できるということ。

多くの端末を作成することを可能にすることで、単一画面からアクセスし、制御することができます。 tmuxは、 画面を表示し、バックグラウンドで実行を続けてから、後で再接続できるとのこと。

よく、macのターミナルやitermなどで作業していると、複数のウィンドウを開いて作業していたことがありますが、 接続が切れてしまったり、どのウィンドウがどこのサーバーだったか見にくくて仕方ないときがありました。

これらをまとめて効率的に作業できるようにしてくれるのが、tmuxといったところ。

さっそく導入してみましょう。

導入

$ brew install tmux

インストールしたら、ヴァージョンを確認してみましょう。 ヴァージョンが確認できたら、正常にインストールできていると思います。

$ tmux -V
tmux 2.8

起動

tmuxの起動は、$ tmux で起動できます。 ローカルで実行するとお馴染みのホームディレクトリが展開されるかと思います。

また、終了するには、$ exit です。

起動が確認できると、ウィンドウ下部に以下(ステータスバー)が確認できるかと思います。

f:id:o21o21:20190123141112p:plain

ここまでではただ同じコンソールを展開しただけなので、tmuxの良さが全然わかりませんねw 少し起動してみましょう。

基本コマンド

起動してから、exitしないで(セッションをデタッチ)ぬけてみましょう。

1, 起動: $ tmux

2, 起動してから: Ctr-b + d

[detached (from session 0)]

3, セッション確認: $ tmux ls

そうすると以下のようなセッションが確認できるかと思います。

0: 1 windows (created Wed Jan 23 14:32:44 2019) [204x62]

どうやら、0がセッション名のようです。(もちろんセッション名は任意の名前に変更可能です。)

4, アタッチ: $ tmux a -t 0

これで再接続できたかと思います。

なんとなーくわかってきたでしょうか。 以下に、基本コマンドを書いておきます。 他にもコマンドはあるので、随時気になるコマンドはググってください!

# セッション一覧表示
$ tmux ls

# セッションアタッチ(再接続)
$ tmux a -t <session_name>

# セッション終了
$ tmux kill-session -t <session_name>

# tmux終了
$ tmux kill-server

tmuxチートシート - Qiita

.tmux.conf

ここからがさらに面白いところです。 tmuxというと、カスタマイズ性にとても優れているようです。 カスタマイズには、.tmux.confというファイルを作成し、そこに設定を記述します。

このファイルはホームディレクトリに作成します。(/Users/<user_name>)

$ touch ~/.tmux.conf

このファイルに記述する内容ですが、けっこう個人に左右されるかと思います。

なので、ここでは必要最低限の設定を紹介します。(ウィンドウの分割など)

あとで、この設定を元に、独自の設定が探せるような状態の設定になればと思います!

# Ctr-bのキーバインドを解除
unbind C-b

# prefixキーをC-qに変更
set -g prefix C-q

# window分割("|": 縦, "-": 横)
bind | split-window -h
bind - split-window -v

# re-size panes by vim movements
bind -r H resize-pane -L 5
bind -r J resize-pane -D 5
bind -r K resize-pane -U 5
bind -r L resize-pane -R 5

# move by vim movements
bind h select-pane -L
bind j select-pane -D
bind k select-pane -U
bind l select-pane -R


# ######## SETTINGS status line

# status line を更新する間隔を1秒にする
#set-option -g status-interval 1

# status-right の最大の長さを指定
set-option -g status-right-length 120

set-option -g status-right '#H#(get_load_average_tmux)#{battery_icon}#{battery_percentage}#(get_ssid_tmux)%m/%d %a#[default] %H:%M'
# ######## SETTINGS status line

set -g @tpm_plugins '              \
  tmux-plugins/tpm                 \
  tmux-plugins/tmux-battery        \
'


# Initialize tpm
run-shell ~/.tmux/plugins/tpm/tpm

コメントに書いてある通りの設定になります。

ステータスバーの編集も可能です。自分の使いやすいようにカスタマイズしてみましょう。 バッテリー残量や日付などの設定が可能です。一応上記のファイルでは設定しています。

tpm

上記のファイルでは、tpm(Tmux Plugin Manager)という、tmuxのプラグイン管理ツールを使用しています。 インストールも簡単なので、使用してみるのがいいと思います。

インストールは以下。

$ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm

インストールしたら、.tmux.confプラグインの名前を記述します。

上記ファイルでいうと、set -g @tpm_pluginsの部分ですね。 そして、必ずプラグインを使用するために、run-shell ~/.tmux/plugins/tpm/tpmをファイルの最終行に記述します。

ここまで記述できたら、tmuxを起動し、prefix(上記ファイルでは、Ctr-q) + I でインストールします。

次のtmux起動で適用されます。 また、プラグインのアップデートは、prefix + Uで、 prefix + alt + uで、記述のないプラグインをアンイストールします。

Tips

  • コンソール起動時に、自動でtmuxを起動(.bash_profileに記述)
if [ $SHLVL = 1 ]; then
  tmux
fi

参考

tmuxで快適なターミナル生活を送ろう - Qiita

tmux の status line の設定方法 - Qiita

【Linux】Linuxの各ディレクトリについて軽くまとめてみた

今回はLinuxのおけるディレクトリについてまとめてみました。

CUIで操作していると、「あれ?このディレクトリってなんのためにあるんけ?」 ってよくその度にググるので、基本情報をまとめました。

Linux

LinuxとはOSの1つであり、Unix系オペレーションシステムカーネルである、 Linuxカーネル、およびカーネルとして周辺を整備したシステムのことである。 厳密にはカーネルのみを指すが、ソフトウェアを組み合わせて1つのソフトウェアパッケージとして提供される。 これを、ディストリビューションと言う。

Linux ディストリビューション

主に、RedHat系とDebian系に大きく2種類に分けられる。

種類については、以下を参照。

Linuxディストリビューション - Wikipedia

よく目にするRHELとは、RedHat系とDebian系に大きく2種類に分けられるEnterpriseLinuxのことで、RedHatの要の製品である。

基礎

Linuxでは、一般的に複数のユーザーが同時に接続できるように構築されているマルチユーザーのOSである。 主に管理者/一般/システムユーザーの3種類である。

管理者はroot(またはスーパーユーザー)で、一般ユーザーはシステムを利用するアカウント、システムユーザーはログイン利用はせず、特定のプログラムを実行するためなどのアカウントになる。

ディレクト

Unix系のOSでは、Filesystem Hierarchy Standard(FHS)といって、ファイルの階層標準が定められている。 だからといって、すべてのLinuxが同じ階層というわけではない。が、ディレクトリの構造が似ている。

/

ルートディレクトリ。 すべてのファイルとディレクトリは / の下に格納される。

/bin

binaries 一般ユーザー向けの基本コマンド群。 (ls, echo, mkdirなどの)どのユーザーでも実行できるコマンド。

Filesystem Hierarchy Standard - 3.4 /bin : Essential user command binaries (for use by all users)

また、基本的にこのディレクトリに新しいコマンドを追加することは推奨されていない。

/usr

User Services and Routines 全ユーザーが使用するアプリのソフトウェアやライブラリ群。

/usr/bin

一般ユーザー向けのの基本でないコマンド群。 言い換えると、/binほど当たり前でないけど日ごろよく使うコマンドを配置する。 AmazonLinux1では、diff, aws, ssh, yumなどが配置されていた。

/usr/lib

/usr/binや/usr/sbinにある基本コマンドの実行に必要なライブラリ群。

/usr/local

ローカルシステムで必要とされるコマンドやライブラリ、ドキュメントなど配置されている。

/usr/local/bin

パッケージ管理ツール以外でインストールした単一ファイルのアプリの格納先に適している。

/usr/local/src

手動でビルドするコードの格納先に適している。

/usr/src

ソースコード群(カーネルソースコードとそのヘッダーファイル群など。)

/usr/share

OSなどに依存しない共有ファイル群。 各アプリで使用されるデータベースや、manコマンドで使用されるマニュアルが格納されている。

/sbin

system bainaries rootユーザー向けのシステム管理コマンド群。 主に、起動/停止/リカバリーなどのシステム管理に必要なコマンドが配置されている。 一般ユーザーでは実行できないように権限が設定されているコマンドもある。

/etc

エトセ(et cetera) 設定ファイル群。システムやアプリに関わる設定ファイルなど。

/lib

システムの起動時に必要なものと、/bin, /sbinにある基本コマンド実行に必要なライブラリ

/lib64

64bitの場合、使用されるライブラリが格納されているディレクトリ。

/opt

option パッケージ管理ツール以外でインストールしたディレクトリ構造になっているアプリ(コード)の格納先。

/etc/opt

optの設定ファイル

/sys

system ドライバ関連のプロセス情報群。

/boot

boot loader システムの起動に必要なファイル群。 普段このディレクトリにあるファイルを変更することは滅多にない。

/dev

device 基本デバイスファイル群。(デバイスもファイルとして扱う) デバイスファイルを、Open,Read,Write,Closeという順にアクセスするようになっている。

/var

variable 一時ファイルを保存しておくディレクトリ。(可変ファイル群) ただし、このディレクトリに格納されているファイルは、サーバーの再起動で削除されない。 ログなど

/mnt

mount リムーバブルメディアを使用するときに利用されるマウントポイント用ディレクトリ。

/media

リムーバブル媒体(DVD-ROMなど)のマウントポイント。

/tmp

temporary files 一時ファイル群。サーバーの再起動で削除される。

/home

各ユーザーのホームディレクトリがあるディレクトリ。

Linuxによって、若干の違いや見たことないディレクトリはもちろん存在します。 また、ヴァージョンアップされたときなど、変更点をチェックするようにしないといけません。 構成管理ツールなどを使用して、自動化をしている場合、ディレクトリの変更や、 システムの起動方法に変更がかかっているとなると、大幅に改修が必要かもしれません。

AmazonLinuxもAL2を使用することができますが、いくつか変更点がやっぱりあります。

Amazon Linux と Amazon Linux 2 の技術面の違い - Qiita

ですが、基礎のディレクトリを把握しておくことで、臨機応変に考えることができそうです。

以上.