読者です 読者をやめる 読者になる 読者になる

ぎじゅつめも

とある工学系学生が学んだことをメモするだけのブログです。

tracerouteの仕様について

tracerouteは、指定したホストまでの経路(経由したノード)を表示するツールです。自社ネットワークで障害が起こった時に“どのノードまではパケットが正常に届いているのか”等を調べる時に使います。もしも使用者が攻撃者であれば“攻撃パケットが標的リンクを通るかどうか”等を調べるために使うこともできるでしょう。また、あるノードまでは応答が早く、あるノードを境に応答が遅くなる場合、このノード間がボトルネックリンクではないかという推測もできます。

このtracerouteですが、IPヘッダのTTL値を利用していることはよく知られています。しかしIP層以上の仕様/実装がWindowsUnix系OSLinux)では違います。この点について、大学の実験実習で学んだのでメモとして書き留めておこうと思います。

各OSでの仕様を知ることは、Firewallでtracerouteを通したい場合等に役に立ちます。また、AS等では当該パケットを観測することでtracerouteが行われたことを認知し、攻撃者による攻撃前の調査パケット(予兆)を得るといったことも可能になるかと思われます。

 

各OS共通の仕様

IPヘッダまでの仕様は各OSで共通です。IPヘッダにはTTLフィールドといものがあります。TTL値は経由できるホップ数を表しており、IPパケットは経由したノードごとにTTL値を1減らされ、0になるとそのノードにおいて破棄されます。tracerouteでは、調査パケットのIPヘッダのTTL値が1の場合,2の場合,3の場合...と試していき、最終的に対象ホストに到達するまでこれを繰り返すというものです。

つまり、tracerouteコマンドを打つと、まずはIPヘッダのTTLフィールド(パケットが経由できるノード数を表すフィールド)を1としたパケットが送りだされます。経由できるノード数は1なので、最初の中継器でパケットが受け取られてTTL値が1減らされ0になるので、パケットは最初の中継器で破棄されます。次のパケットはTTL値が2なので、2つ目の中継器で破棄されます。次のパケットはTTL値が3なので、3つ目の中継器で破棄され...という風に対象ホストに至るまでのそれぞれのノードで破棄されるパケットがでてくるのです。

traceroute実行ノードは、これらの破棄されたノードからの応答を受け取ることで、対象ホストまでの全ルートを得ます。

 

Windwosでの仕様

Windowsではtracerouteはtracertコマンドとして実装されています。Windowsでのtracerouteは簡単に言うとpingです。すなわち、IPの上層はICMPとなっています。traceroute実行ノードによる調査パケットは全てICMP type8 code0(echo request)として送られます。ただし、それぞれの中継ノードではTTL値が0になってパケットは破棄されるので、中継ノードからtraceroute実行ノードに対してICMP type11 code0(time exceeded)が返されます。唯一宛先ホストのみが、echo requestに対する応答として、ICMP type0 code0(echo reply)を返します。

traceroute実行ノードはecho replyが返ってきたら宛先ホストまでのtraceが完了したと解釈することができます。ちなみにそれぞれの応答(time exceededおよびecho reply)内には送信者の情報が記載されているので、traceroute実行ノードは中継ノードの情報を得られます。

 

※補足

ちなみに、tracerouteでは実行ノードとそれぞれの中継器間の情報(RTT等)しかわかりませんが、現行のWindowsでは中継器間の情報もわかるpathpingなるものがあったりするそうで…

 

Unix系OSLinux)での仕様

Linux等では、IPパケットの中身はICMPではなくUDPになっています(ただし指定すればICMPでも可能)。UDPヘッダの宛先ポート番号を、絶対に使われていないであろうポート番号に設定して送ります。TTL値が0になる中継ノードからは、実行ノードに対して、Windowsのtracertと同じようにICMP type11 code0(time exceeded)が返されます。しかし、宛先ホストには待ちうけていないポート宛ての要求が来たのでパケットを破棄し、実行ノードに対してICMP type3 code3(port unreachable)を返します。

実行ノードはport unreachableを得れば宛先ノードまでのtraceが完了したと判断します。以下はtraceroute後の宛先からのport unreachableをwiresharkで実際にキャプチャした際の画像です。

f:id:white-hawk:20170210034547p:plain

 

※補足

ちなみに、実際に使われるであろう宛先ポートを指定すると、運用されているサービスから応答が来てしまう可能性があるので、使われていないポートを指定します。また、メジャーなサービスの宛先ポート番号はウェルノウンポートとなるので、多くの実装では33434からインクリメントしてパケットを送信しますので、Firewallでもしtracerouteを通す場合これを意識するといいと思います。また念のため1度に2つ(資料によっては3つ)調査パケットを送るようです。(つまり1つのTTLに対して異なる宛先ポート番号を指定した2つ又は3つのパケットを送ります。)

 

結論

IP層より上層で使うプロトコルと、それに伴った宛先ホストまで到達したかどうかの判断方法が異なります。

 

今後のtraceroute関連の記事について

tracerouteの高速化については前から興味がありましたので、tracerouteのコードなんかを見ながら記事がかければなーと思います。あとtracerouteを応用した研究等(既存のものでいうと某大学様のASパス推測など)についても言及できればと思います。

Linux(CentOS)のディレクトリ構造

サーバをいじりはじめて最初に感じたのが、各ディレクトリの意味をちゃんと理解できていないなーということでした。

サーバを管理する上では吐かれたログを見たり、システムの設定をいじったりしないといけないので、ディレクトリ構造については知っておくべきだと思い、現行のディレクトリ構造の標準などについて調べてみました。

※間違いがあったら指摘して戴けると嬉しいです。

 

目次

 

 

FHS(Filesystem Hierarchy Standard)について

FHSはLinuxディストリビューションの多くが従っているファイルシステム階層に関する標準だそうです。自分が利用しているCentOSもこれに則っているようです。

2017年1月現在での現行標準はv3.0のようです。

 

ファイルシステムとは、記憶装置に格納されたデータ(ファイル)を、ユーザが操作できるようにするためにOSが提供している機能です。複数の関連するファイル(及びディレクトリ)を束ねるのがディレクトリになります。

Windows系OSではデバイスごとにツリー構造を持ちますが、UNIX系OSでは、すべてのデバイス上のファイルをひとつの階層構造(木構造)のいずれかのディレクトリ内に配置する仮想ファイルシステムになっており、この木構造の根にあたるのがルートディレクトリになります。

 

ディレクトリ構造

 Linuxファイルシステム最上位はルートディレクトリ("/")です。※ルートディレクトリは厳密には/直前の空白らしいのですが/と表すのが慣例となっています。

その直下のディレクトリは下記のようになっています。

 

名前格納される内容
/bin

最低限必要な基本コマンドの実行ファイル(binaries)が格納されている。 例えば、chmod、sh、ls、cp、pwd、chown、psなど。

※/usr/binと違いシングルユーザモードで使う最低限のもの置いている点。/binにないものを/usr/binに置いている。

/boot 起動(ブート)に必要なファイル。カーネルの他にもinitrd等が含まれる。
/dev 接続されたデバイスを制御する際に用いるデバイス・ファイル(スペシャル・ファイル)が置かれる。データ入出力を1文字(バイト)単位で行うマウス・キーボードのようなものをキャラクタデバイス、ある一定の大きさ(ブロック)単位で行うHDD・メモリ・FDのようなものをブロックデバイスと呼ぶ。 デバイスファイルに対し、open()などのシステムコールを用いると、カーネルドライバがファイルではなくデバイスへアクセスする仕組みになっている。 主なデバイスファイル名とその詳細については以下のようになる。
hda IDE接続されたデバイスを表す(HDDである必要はない)。接続されるデバイスごとにhda,hdb,hdc...と命名される。また、HDDにパーティションがある場合パーティションごとのファイルも生成される。(例えば、sdaに3つのパーティションがある場合hda1,hda2,hda3)
sda SCSI接続されたデバイスを表す。命名規則は同上。
null nullデバイスを表す。nullデバイスは実体がない仮想的なデバイスの一つで、書き込んでも捨てられ読み出しても何も得られないデバイス。出力を捨てる際に用いる。
zero zeroデバイスを表す。zeroデバイスは実体がない仮想的なデバイスの一つで、書き込んでも捨てられ読み出すと0を得つづけることができるデバイス。
random 乱数生成器を表す。
stdin 標準入力(デフォルトではキーボード入力)を表す。
stdout 標準出力(デフォルトではコンソール画面)を表す。
stderr 標準エラー出力(デフォルトではコンソール画面)を表す。
tty 標準入出力となっている端末を表すデバイスファイル。teletypewriterの略称。
pts sshtelnetで接続する仮想端末のデバイスファイル。
/etc

固有の設定ファイルが置かれる。設定ファイルの拡張子と定義されているわけでないものの、confとつくものが割とある。例えばWebサーバの設定はhttpd.conf(httpd/conf)などとして置かれる。

/home ユーザのホームディレクトリ。
/lib /bin配下や/sbin配下にある実行ファイルに必要なライブラリ。
/media リムーバブルなデバイスのマウントポイント。
/mnt ファイルシステムの一時的なマウントポイントで、通常は空である。
/opt アプリケーションのパッケージのインストール用。
/proc

procfs(process filesystem)というプロセスの情報をファイルシステムに見せかけたものをマウントするディレクトリ。ここではプロセスや場合によってはカーネルの情報が置かれる。

/root rootユーザのホームディレクトリ。
/sbin システム管理関係のコマンド実行ファイルが置かれる。
/tmp 一時的に利用するファイル置き場。システムを再起動したときには消去されている。
/usr マルチユーザで共有可能なリソース、アプリケーションが置かれるディレクトリ。
/usr//bin /binに置かれなかったコマンドが置かれる。すなわちシングルユーザモードでは必要ないようなもの。
/usr/local ユーザがインストールしたソフトウェア等が置かれるディレクトリ。
/var 内容が変化する可変データが置かれるディレクトリ。ログファイルやアプリケーションキャッシュなど。

 

この他にもディストリビューションやOSごとに固有のディレクトリだったり、インストールしたサブシステムによって追加されるディレクトリがあるようです。自分のCentOSではselinuxという強制アクセス制御のためのディレクトリ等もありました。


 

補足

■initrdとはなんぞや

聞いたことがあってもよくわかっていなかったものの一つです。Wikipediaさん曰く次の通りらしいです。

初期RAMディスク(initial ramdisk)はLinuxカーネルブート時に一時的なルートファイルシステムをメモリに読み込むための方式。

initrd - Wikipedia

カーネルのbootにはファイルシステムを参照しないといけないが、ファイルシステム構築にはカーネルが必要という矛盾があり、これを打開するため、カーネルブート時には一時的なファイルシステムをメモリ上に展開するということでしょうか…?

うーん確信が持てない…ということでさらに調べていくとめちゃくちゃわかりやすく解説されていらっしゃるサイト様がありましたので、リンクを張っておきます。

Linuxのinitrdファイルの作成

つまりポイントは以下

  • 現状のLinuxでは、カーネルはモジュール化により各種ドライバを内包していない。なぜなら、ドライバをすべてカーネルに内包させると容量が肥大化するため。現在は必要に応じてモジュールをカーネルに組み込む形を取っている。
  • つまりブート時にカーネル単体をメモリ上に展開しても、ドライバがないのでHDDを認識できない問題が起こる。
  • initrdはブートする際に必要なHDDドライバなどのモジュールを、カーネルと一緒にメモリに展開するために記述されるファイル

モノリシックカーネルとドライバのモジュール化についても勉強になりましたので、ブートの仕組みやこれらについても後で改めて別記事にまとめようと思います。
 

自宅サーバのスペック等

前置き

サーバ構築・運用技術を養うために自宅でWebサーバ等を構築していきたいと思います。幸いマシン自体は5年前に購入したものがあったので、これを利用したいと思います。

古いモデルですが、勉強用途として使う分にはどうなのか、電力消費量はどうなのかなど今後体感したことをちょこちょこ書いて行きたいと思います。その際に、同じく勉強中の読者の方の後学になれば良いなということで簡単にサーバのスペックを記載しておきます。

 

サーバのスペック

マシンスペック

製品:HP  ProLiant MicroServer N54Lモデル(ディスクレスモデル)

リソース名

詳細

プロセッサ

AMD Turion(TM) Ⅱ NEO N54Lプロセッサー(2.2GHz)

キャッシュメモリ

1MB L2×2

メモリ

4GB×1

HDD

250GB×4

※(R)や(TM)は登録商標について表すものです。

  f:id:white-hawk:20170126025213j:plain

搭載OS 

CentOS 6.7

Ubuntuは大学で利用しており、別のディストリビューションも触ってみたかったのでCentOSを選択しました。もしかしたら今後変更することもあるかもしれませんが、とりあえずこれで行こうと思います。

プロフィール

書いてる人

寝ることとおいしいご飯を食べることが好きな、そこらへんの工学系の学生です。

専攻は機械だったこともあれば電気だったこともあります。現在は情報です。

はてなID(white-hawk)は好きな色と好きな動物を組み合わせただけなんですが、厨二病っぽくなってしまいました。 

 

ブログで書くこと

ちょっぴり社会経験を積んでみて、実践的な技術力が欠けていると感じたので、実践的な取り組みを行ったりして学んだことをメモしていこうと思いブログを開設しました。

実践的な技術だけでなく理論寄りの記事も書くかもしれません。

勉強中の身ですので、もし記述内容に間違いがあった場合指摘して戴けると嬉しいです。

また、たまにおいしいご飯に関する記事も書くかもしれませんがご了承ください。

 

スキル・知識的なもの

 ブログ開設以前に身につけたスキル・知識

  • C言語プログラミング(データ構造とアルゴリズムの理解)
  • C#.NETによるGUIプログラミング
  • Javaを用いたGUIプログラミング
  • 情報通信ネットワークの基礎理解

今後身につけたいスキル・知識

  • Linux系OSの仕様とコマンドの把握
  • サーバ運用ノウハウ
  • ネットワーク機器の設定
  • セキュリティに関するスキル全般(マルウェア解析など)
  • Webプログラミング
  • Ruby,Python
  • 電子工作