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

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


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

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

先日、久しぶりに、某 MS の無料セミナーに参加してきました。

いわゆる MS のセミナーですので、コンプライアンスだのダイバーシティだの、 ビジネスな横文字のオンパレードで、 脳みそがついていけない私はちょっと気持ちが悪くなってしまいました。

そんな中で面白かったのが、来場者の iPhone 所有率です。
あちこちで iPhone をいじっているひとを見かけました。
となりの知らないひとも、セミナー中につぶやいておられました。
(バルマーさんに見つかったら、即座に踏みつけられるでしょうに…。)

それはさておき、よめと子どもが風邪でへたっていましたので、 得られる情報を得たところでスピード帰宅したのですが、帰ってきたとたん、 今度は私が風邪でダウンしてしまいました。

気持ち悪かったのは、ビジネス横文字のせいではなく風邪のせいでした。
その日は、超弩級の気持ち悪さが夜中まで続きましたが、上からの出力をこらえつつ、 下からの出力を何度も行うことで、なんとかしのぎました。

というわけで、みなさまも、この季節の風邪には十分ご注意ください。
ほんとうにつらいですので…。

さて、風邪はほぼ治りましたので、今週もはりきってまいりましょう!

今回のお題 - D-Bus の存在をもう少し感じてみる

前回は、D-Busの超概要と、dbus-sendによる通信のお試し的使用方法を、 簡単にご紹介しました。

Vol.175 - D-Bus の存在を感じてみる
http://www.usupi.org/sysad/175.html

読者数が激減した…という現実に直面することはありませんでしたので、 気をよくして、D-Bus の続編をご紹介させていただきます。

具体的には、前回ご紹介に至らなかった、NetworkManagerさんとやりとりする方法と、 D-Bus から指令を受けてなにか処理するひとを作成する方法という、 微妙な2本立てで進めていきたいと思います。

よく考えますと、前回以上にシステム管理ネタでなくなっておりますが、 そのあたりは感じないようにしていただけますと幸いです。

NetworkManager とやりとりする

まずは、dbus-sendコマンドで、NetworkManager さんから情報を得たり、 接続を変えてみたりしたいと思います。
NetworkManagerさんのインターフェースの仕様は、以下にあります。

NetworkManager D-Bus Interface Specification
http://projects.gnome.org/NetworkManager/developers/spec-08.html

いちおう、前々回にご紹介した、cnetworkmanager で示した例と似たことを、 dbus-send コマンドで行っていきたいと思います。

Vol.174 - NetworkManager をもう少し活用してみる
http://www.usupi.org/sysad/174.html

 

最初は、 本家本元の org.freedesktop.NetworkManager インターフェースにある GetDevices メソッドで、デバイスの一覧を入手します。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply /org/freedesktop/NetworkManager \
  org.freedesktop.NetworkManager.GetDevices
  method return sender=:1.3 -> dest=:1.185 reply_serial=2
     array [
        object path "/org/freedesktop/NetworkManager/Devices/0"
        object path "/org/freedesktop/NetworkManager/Devices/1"
     ]

ただし、ご覧の通り、オブジェクトの配列が返るだけです。
これは、org.freedesktop.NetworkManager.Device のオブジェクトの配列です。 このオブジェクトには、いくつかのプロパティがあります。
ですので、プロパティを参照することで、詳細がわかります。
たとえば、Ip4Address にはIPアドレスが設定されています。
ですので、/org/freedesktop/NetworkManager/Devices/0 の Ip4Address を、 以下のようにして得てみましょう。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply \
  /org/freedesktop/NetworkManager/Devices/0 \
  org.freedesktop.DBus.Properties.Get \
  string:"org.freedesktop.NetworkManager.Device" string:"Ip4Address"
  method return sender=:1.5 -> dest=:1.204 reply_serial=2
   variant       uint32 3540101312

わかりにくいですが、3540101312 を16進数にして(0xd301a8c0 です) 逆順にしますと、0xc0a801d3 になります。
あとは、各バイトを 10進数に戻しますと、192.168.1.211 となります。
…ああ、ややこしいですね。
また、Interface にはインターフェース名が格納されています。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply \
  /org/freedesktop/NetworkManager/Devices/0 \
  org.freedesktop.DBus.Properties.Get \
  string:"org.freedesktop.NetworkManager.Device" string:"Interface"
  method return sender=:1.5 -> dest=:1.205 reply_serial=2
   variant       string "eth0"

こちらは、素直に文字で返ってきます。

 

次に、アクティブな接続を調べてみましょう。
org.freedesktop.NetworkManager のプロパティ ActiveConnections が、 アクティブな接続を示しています。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply /org/freedesktop/NetworkManager \
  org.freedesktop.DBus.Properties.Get \
  string:"org.freedesktop.NetworkManager" string:"ActiveConnections"
  method return sender=:1.5 -> dest=:1.215 reply_serial=2
   variant       array [
     object path "/org/freedesktop/NetworkManager/ActiveConnection/7"
   ]

こちらも、オブジェクトの配列が返ってきます。
これは、org.freedesktop.NetworkManager.Connection.Active の配列になります。
詳細を得るため、org.freedesktop.NetworkManagerSettings.Connection のオブジェクトが格納されているプロパティ Connection を参照します。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply \
  /org/freedesktop/NetworkManager/ActiveConnection/7 \
  org.freedesktop.DBus.Properties.Get \
  string:"org.freedesktop.NetworkManager.Connection.Active" \
  string:"Connection"
  method return sender=:1.5 -> dest=:1.218 reply_serial=2
   variant object path "/org/freedesktop/NetworkManagerSettings/2"

このオブジェクトの GetSettings メソッドで設定内容を確認できます。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply \
  /org/freedesktop/NetworkManagerSettings/2 \
  org.freedesktop.NetworkManagerSettings.Connection.GetSettings
  method return sender=:1.5 -> dest=:1.219 reply_serial=2
     array [
        dict entry(
           string "ipv4"
           array [
              dict entry(
                 string "addresses"
                 variant                   array [
                       array [
                          uint32 3540101312
  ...

人様にお見せする形式ではないため見づらいですが、 一通りの設定内容を全部返してくれます。(上記は、IPアドレス部分だけを示しています。)

 

今度は、アクティブじゃないものも含めた設定の一覧を得てみましょう。
org.freedesktop.NetworkManagerSettings の ListConnection メソッドで得られます。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --type=method_call --print-reply \
  /org/freedesktop/NetworkManagerSettings \
  org.freedesktop.NetworkManagerSettings.ListConnections
  method return sender=:1.5 -> dest=:1.220 reply_serial=2
     array [
        object path "/org/freedesktop/NetworkManagerSettings/0"
        object path "/org/freedesktop/NetworkManagerSettings/1"
        object path "/org/freedesktop/NetworkManagerSettings/2"
     ]

…はい、例によってオブジェクトの配列です。
先ほどと同様、 org.freedesktop.NetworkManagerSettings.Connection のオブジェクトですので、 GetSettings メソッドで設定を確認できます。

 

それでは最後に、接続を切り替えてみたいと思います。
切り替えには org.freedesktop.NetworkManager の ActivateConnection メソッドを使用しますが、引数が4つもあります。
(そういえば、cnetworkmanager も同様に4つありましたね。)

最初の引数は、「全てのユーザに有効」か否かを指定するためのもので、 そうならば org.freedesktop.NetworkManagerSystemSettings を指定し、 違うなら org.freedesktop.NetworkManagerUserSettings を指定します。

2番目の引数は、使用する設定をオブジェクトで指定します。
先ほども出てきた org.freedesktop.NetworkManagerSettings.Connection のオブジェクトですね。

3番目の引数は、使用するデバイスをオブジェクトで指定します。
org.freedesktop.NetworkManager.Device のオブジェクトですね。

4番目の引数は、とりあえず "/" を指定すればよいようです。

というわけで、実行例を以下に示します。
org.freedesktop.NetworkManager.Connection.Active のオブジェクトが返ることがわかると思います。

  $ dbus-send --system --dest=org.freedesktop.NetworkManager \
  --print-reply --type=method_call /org/freedesktop/NetworkManager \
  org.freedesktop.NetworkManager.ActivateConnection \
  string:"org.freedesktop.NetworkManagerSystemSettings" \
  objpath:"/org/freedesktop/NetworkManagerSettings/1" \
  objpath:"/org/freedesktop/NetworkManager/Devices/0" objpath:"/"
  method return sender=:1.3 -> dest=:1.260 reply_serial=2
     object path "/org/freedesktop/NetworkManager/ActiveConnection/8"

D-Bus から指令を受けて処理するひとを作ってみる

さて、ありものを突っつくだけでは、なんとなくもの足りません。よね。
ですので、実際に、指令を受けて処理する側を作ってみましょう。

具体的には、ログ(/var/log/messages)を参照するものを作成したいと思います。

たいていのディストリビューションですと、 root 自身や adm グループに属するひとしか、 ログを参照できないようになっていると思います。

  $ less /var/log/messages
  /var/log/messages: 許可がありません

しかし、いちいち root 権限で参照するのって、面倒ですよね。
もちろん、セキュリティ上好ましくないということはわかっていますが、 それを千も承知した上で、D-Bus を介して、だれでも見られるようにしてしまいます。

そして、そのようなものを、例によって Perl で書いております。
そのため、 libnet-dbus-perl (Debian系) か perl-Net-DBus (RedHat系)というパッケージが、 以降では必要になります。
もしなければ、下記のように、apt や yum で仕入れてください。

  # yum install perl-Net-DBus (RedHat系の場合)
  # apt-get install libnet-dbus-perl (Debian系の場合)

インターフェースは、org.usupi.showlog という安直な名前にしました。
これは、最近のログの内容を返す Get メソッドと、 指定した文字を含むログを返す Grep メソッドを持っています。

というわけで、試行錯誤の末、以下の Perl スクリプトになりました。
(スクリプトの説明は、紙面の都合上、ばっさり割愛させていただきたいと思います。 ご了承くださいませ。)

  #!/usr/bin/perl
  use strict;
  use Net::DBus;
  use Net::DBus::Reactor;

  package Usu::DBus::Test;
  use Net::DBus::Exporter qw(org.usupi.showlog);
  use base qw(Net::DBus::Object);
  my $LOG = "/var/log/messages";

  sub new {
      my $class = shift;
      my $serv = shift;
      my $self = $class->SUPER::new($serv, "/org/usupi/showlog");
      bless $self, $class;
  }

  sub Get {
      my $self = shift;
      my $line = shift;
      my $ret = `tail -$line $LOG`; # 危険!!
      $ret;
  }
  dbus_method("Get", ["uint32"], ["string"]);

  sub Grep {
      my $self = shift;
      my $pattern = shift;
      my $ret = `grep $pattern $LOG`; # 危険!!
      $ret;
  }
  dbus_method("Grep", ["string"], ["string"]);

  package main;

  my $ifname = "org.usupi.showlog";
  my $obname = "/org/usupi/showlog";
  my $dbus = Net::DBus-%gt;system();
  my $service = $dbus->export_service($ifname);
  my $object = Usu::DBus::Test->new($service);
  my $reactor = Net::DBus::Reactor->main();
  $reactor->run();

コメントに "危険!!" と書いてある箇所は、確認をはしょっております。
得られた値をそのままコマンドの実行に渡していますので、 root の権限であらぬことを実行できてしまうと思います。
ですので、お試しじゃなく使われる場合には、 少なくともここはちゃんと実装していただきたいと思います。(他力本願ですみません。)

さて、上記を showlog-serv.pl という名前で保存しましたら、いつものように、 実行可能な状態にしておきます。

  # chmod +x showlog-serv.pl

それから、システムバスは、デフォルトではアクセスが禁止されていると思いますので、 穴を開ける細工が必要です。
そのため、/etc/dbus-1/system.d/ の下に、穴を開けるためのファイルを置きます。 ファイル名は org.usupi.showlog.conf で、内容は以下の通りです。 (お察しの通り、だれでもウェルカムな設定にしています。)

  <!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus 
   Configuration 1.0//EN"
   "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
  <busconfig>
      <policy context="default">
          <allow own="org.usupi.showlog" />
          <allow send_destination="org.usupi.showlog" />
          <allow receive_sender="org.usupi.showlog" />
          <allow send_path="/org/usupi/showlog" />
      </policy>
  </busconfig>

上記のファイルを置きましたら、後は root 権限で実行するだけです。

  # ./showlog-serv.pl

上記を実行した状態で、動作確認してみましょう。
まずは、Get メソッドを用いて、最新の5行を取り寄せてみましょう。

  $ dbus-send --system --dest=org.usupi.showlog --type=method_call \
  --print-reply /org/usupi/showlog org.usupi.showlog.Get uint32:5
  method return sender=:1.192 -> dest=:1.195 reply_serial=2
     string "Mar 21 16:01:00 tamao kernel: i915 0000:00:02.0: HDMI \
  Type A-2: no EDID data
  ...後略..."

一般ユーザでも、問題なく参照できると思います。
次に、"eth0" という文字を含むログを、Grep メソッドで取り寄せたいと思います。

  $ dbus-send --system --dest=org.usupi.showlog --type=method_call \
  --print-reply /org/usupi/showlog org.usupi.showlog.Grep string:eth0
  method return sender=:1.196 -> dest=:1.199 reply_serial=2
     string "Mar 21 11:10:31 tamao kernel: ADDRCONF(NETDEV_UP): \
  eth0: link is not ready
  Mar 21 11:10:32 tamao kernel: e1000e: eth0 NIC Link is Up 100 Mbps \
  Full Duplex, Flow Control: RX/TX
  ...後略..."

いかがでしょうか。大丈夫そうですね。

はい、もちろん、 org.freedesktop.DBus.Introspectable の Introspect メソッドも使用できます。 ちゃんと上記メソッドを教えてくれました。

  $ dbus-send --system --dest=org.usupi.showlog --type=method_call \
  --print-reply /org/usupi/showlog \
  org.freedesktop.DBus.Introspectable.Introspect
  method return sender=:1.196 -> dest=:1.202 reply_serial=2
  ...
    <interface name="org.usupi.showlog">
      <method name="Get">
        <arg type="u" direction="in"/>
        <arg type="s" direction="out"/>
      </method>
      <method name="Grep">
        <arg type="s" direction="in"/>
        <arg type="s" direction="out"/>
      </method>
  ...

おわりに

以上、D-Bus の続き的な内容をご紹介しました。

実際にこれらを使ってなんらかのシステム管理を行う… という機会はないかもしれませんが、D-Bus というものが各所で使われている以上、 仕組みなどを知っておくことは悪いことではないと思います。

後半のスクリプトは話半分で(?)読むだけでも構いませんが、 前半の確認は実際にやってみてくださいませ。(いますぐ実践! です。)

ずいぶん脱線してしまった気がいたしますので、次回からは、 まっとうなシステム管理ネタに戻していこうと思います。(全力でネタを探します。)

宿題の答え

前回の宿題は、

  org.gnome.ScreenSaver といろいろ通信してみましょう。

という微妙なものでした。

まずは、インターフェースの確認から行ってみましょう。

  $ dbus-send --session --dest=org.gnome.ScreenSaver \
  --type=method_call --print-reply /org/gnome/ScreenSaver \
  org.freedesktop.DBus.Introspectable.Introspect

org.gnome.ScreenSaver というインターフェースに、いくつかのメソッドがあります。

まず、SetActive メソッドを用いますと、スクリーンセーバを即座に起動させたり、 起動を止めることができます。
たとえば、即座に起動するには、以下のように実行します。

  $ dbus-send --session --dest=org.gnome.ScreenSaver \
  --type=method_call --print-reply /org/gnome/ScreenSaver \
  org.gnome.ScreenSaver.SetActive boolean:true

また、スクリーンセーバの起動の有無を GetActive メソッドで、 動作中の場合の起動時間を GetActiveTime メソッドで確認できます。
…といっても、いま確認のために実行したら、 スクリーンセーバが動作中だったとしても、止まってしまいますよね。
ですので、at コマンドを使って、 スクリーンセーバが起動するくらい後に実行されるようにしてみましょう。
たとえば、現在の時刻が 22:00 で、10分後の 22:10 に実行させるには、 以下のように実行します。
(スクリーンセーバを、10分より短い時間で起動するように設定しておく必要があります。)

  $ at 22:10
  at> dbus-send --session --dest=org.gnome.ScreenSaver \
  --type=method_call --print-reply /org/gnome/ScreenSaver \
  org.gnome.ScreenSaver.GetActiveTime > ~/screensaver.out
  at> (Ctrl-d を押下)

出力結果を、 ホームディレクトリ直下の screensaver.out という名前のファイルにリダイレクトしています。
さて、その間 PC に触らないようにしまして、22:10 を過ぎたところで、 screensaver.out の内容を確認します。

  $ cat ~/screensaver.out
  method return sender=:1.18 -> dest=:1.552 reply_serial=2
     uint32 341

スクリーンセーバが341秒(約5分40秒)動作していたようです。

他にもスレッドなどがありますので、いろいろ試してみてください。
ちなみに、スクリーンセーバの仕様は、以下にあるようです。

GNOME Screensaver 2.15.3 Documentation
http://people.gnome.org/~mccann/gnome-screensaver/docs/gnome-screensaver.html

今回の宿題

今回の宿題は、

  ところで、D-Bus はなにを使って通信しているのでしょうか?

です。

これまた私は存じ上げませんので、 またしても見切り発車的かつおのれの首を締める的な宿題でございます。

最悪、ソースを斜め読んで確認したいと思います。
それまでに、なにを使っているのか、想像しておいてくださいませ。

あとがき

あちこちで紹介されていますので、ご存じの方も多いと思いますが、 個人的にすげーと思いましたので、今さらながらご紹介させていただきます。

turizuki日記 100体のマルウェアでセキュリティテスト
http://turizuki360.blog112.fc2.com/blog-entry-57.html

マルウェアを100個、PC に放り込んで、 18個のセキュリティソフトに検出させたらどうなるか、 というすごい動画が公開されています。

マルウェアを100個集めたというのもすごいですし、 セキュリティソフトを18個も集めたというのもすごいです。
しかし、もっともすごいのは、これをやったのが中学生というところではないでしょうか。

うちの子も中学生(1年)ですが、マルウェアがどういったものなのかを、 漠然とでもわかっていないと思います。
こんな中学生がいたら、中学の先生は教えづらいだろうなと思いました。
(世の中には、 もっとすごいスーパープログラマーな中学生とかスーパーハッカー(?)な小学生とかいるのかもしれませんが。)

コメント欄もなかなか興味深いですので、 隅々まで斜め読むとよろしいのではないかと思います。

 

ところで、セキュリティソフトといえば、栗画をみてくださっている読者の方が、 以前、セキュリティソフトでトラブっておられました。

具体的には、「ウィルスバスター」を使っていると Vista の動作が猛烈に遅い、 というものでした。
そのため、別のソフト… 具体的には「ウィルスセキュリティゼロ」に乗り換えたそうなのですが、 今度はウェブのページがまったく見られない現象に遭遇したり、 更新が全然行われなくなったりしたそうです。
(あ、ウェブが見られないというのは、設定を変えたら回避できました。 わたしが貢献できたのは、唯一この点だけでした…。)

私自身はセキュリティソフトを使っていませんので、 ウィルスバスターやウィルスセキュリティゼロがどんな塩梅なのか、 ひとごとのように興味が沸きまして、 上記の動画を拝見させていただいたという次第です。

さて、それらの気になる結果は… 実際に上記をご確認くださいませ。:-)

 

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

 

「いますぐ実践! 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

▼ せんでん




▼ 最近読んだ本

▼ 気に入ってる本