授業資料/第05回 の変更点

Top / 授業資料 / 第05回

* Unix が動いているということ [#l5c68048]

unix という OS が動いているということは,ユーザに対してさまざまな直接に応答をするだけではない.
さまざまな応答を「サービス」するために,背後で常に動いているソフトウェアがあったり,要求に応じてソフトウェアが自動的に立ち上がったり,定期的に起動したりするソフトウェアがある.

希望通りのサービスを行わせるためだけではなく,動作の効率化の面からもセキュリティの面からもこうしたソフトウェアの在り方と設定を知ることが必要である.
今回はそうした「自動的に起動するソフトウェア」について学ぶ.

* 常に動いているソフトウェア [#z70430d0]

unix に限らず,ある程度の規模の OS ではさまざまなサービスを提供するために常に動いているソフトウェアが存在する.

** 動いているソフトウェアを見るには? [#n6310b93]

 ps -axu 

としてみると,全てのプロセスが見える. 
ある程度の文字数で表示が切られてしまい良く読めないという場合は,

  ps -axuww

などとしよう.

  top

とすると,プロセスの状況が動的にみえ,かつ,cpu やメモリの状況などがみられる.

 lsof -i4 -i6 
 lsof -i4 -i6 -P

とすると,どの port でどんなソフトが待ち受けているかが分かる(root でやるべし).
ただし,lsof はインストールが必要だ. ports からさくっとインストールしておこう.

*** 実習 [#p2060066]
lsof をインストールしておけ.

** kernel [#acea2691]

OS そのもの,中核であるソフトウェアは通常 kernel と呼ばれ,常に動いている.
kernel の役目はその OS 上で動くソフトウェアの制御と,各ソフトウェアに資源(メモリ,ハードディスク,各 I/O 等々)を提供することにある.
具体的には,CPU やメモリなどのハードウェアの基本的な制御,その上での抽象的な資源(仮想メモリなど)の構築, 各ソフトウェアへの資源割り当て((マルチタスクはCPUなどの資源を順番に割り当て直すことで実現される))などであり, unix OS のソフトウェアの中で「もっとも重要なソフトウェアの一つ」である.

kernel は現在の FreeBSD では /boot/kernel ディレクトリにある. 

kernel の動作を変えるには,設定を変える方法と kernel 自身をコンパイルして作り直す方法がある((なんと OS の中核そのものを自分で作り直すことができるのだ)).
詳しく書くと以下の通りである.

- 起動時に設定を変える方法 
-- ブートローダに「入って」そこで手動で書き換える: 起動時のメニューが出た時に 6 を選べばローダに入れる.  ローダの上では ? を押せば使えるコマンドが出る. ローダの中で困ったら,autoboot とすれば通常通り起動するのでこれを使おう.
-- /boot/loader.conf を書き換えておいてから(再)起動する. この設定ファイルのデフォルト設定は /boot/defaults/loader.conf にあるのでみてみよう.

- 動作中に設定を変える方法.
-- sysctl を使う. 情報をみるだけなら問題ないので,root で
  sysctl -a -h | less
などとしてみよう. ちなみに,書き換えてみたければ sysctl -w 云々 であるが,あまりお勧めしない(^-^)
-- カーネルモジュールのロード,アンロードを行う. コマンドは kldload と kldunload だ. デバイスドライバの設定をあれこれ変える場合などにお世話になるだろう.

- カーネルをコンパイルして作ってしまう(かなり細かいカスタマイズが可能)
普通は,/usr/src/sys/i386/conf にある GENERIC ファイルをコピーして書き換えてからコンパイルし直すという手順を踏む.
さすがにここで書ききれないので,FreeBSD の公的資料である [[ハンドブック(FreeBSDカーネルのコンフィグレーション)>http://www.jp.freebsd.org/www.FreeBSD.org/doc/ja_JP.eucJP/books/handbook/kernelconfig.html]] を紹介しておく.
この手法でFreeBSD の「性能」を大きく変えることができるので,マシンの用途によってはカーネルの再コンパイルを検討した方がよいだろう.

*** 実習 [#x24db7ca]
ローダに入ってみよう.
sysctl の設定表を眺めて,分かる部分がないか探してみよ.

** init [#ke7bd156]

unix OS の中で「プログラム」として意識されるプログラム/プロセス全ての「始祖」プログラムである.
通常は pid 1 である((さらに nest して init を起動することが可能な環境が存在する. 詳しくは jman jail などとしてみよ.)).

unix では init を除いてあらゆるプロセスは「親プロセス」をもっており,親プロセスが死んだときにはその子プロセスも死ぬことになっている.
であるので,全てのプロセスの遠い親にあたる init が死ぬとシステムがリブートするなど,init の挙動はシステム全体に大きな影響を与える.
init は起動後,/etc/rc, /etc/rc.subr, /etc/rc.conf などを読み,その設定に従って主に /etc/rc.d/以下にあるさまざまな daemon を起動するという流れで様々なソフトウェアを起動する.
より詳しくは,init のマニュアルを参照されたい.

*** 実習 [#v45e760e]

init のマニュアルを読むとカーネルのセキュリティレベルについての記述がある.
先の sysctl の出力でこれに相当するのはどこか調べよ((マニュアルをよく読むか,sysctl -a -h の結果に適切に grep すればよいよね)).
そして,その値が今どうなっているか調べよ.

また,init のマニュアルを読むと,kill ほげほげ 1 についていくつか解説が載っている.
それらを理解した上で,
  kill -INT 1
を行ってみよ(ただし,root でないと出来ないかもしれないよ).

** Daemon [#yed897f0]

なんらかのサービスを提供するためにバックグラウンドで常時動いている(もしくは呼び出されたら即時起動するも)ソフトウェアは一般に daemon (ダイモン,デーモン)((daemon は守護神とか,ギリシャ神話に出てくる半神半人のことで,悪魔(demon)ではないことに注意せよ. 綴りが違う. まあアメリカ人でもよく誤解するわけだが. なお,BSD 系 unix では daemon はマスコットとしての重要な役割がある. 詳しくは http://www.freebsd.org/ja/copyright/daemon.html を見よ. ))と呼ばれる.
いずれ細かく示すが,その unix で何ができるのかは daemon をみれば大体分かる.
まずはどんな daemon が今動いているのか,名前だけでもみてみよう.

*** 実習 [#g97d577d]
ps, top, lsof についての操作をしてみて,今現在どのようなソフトウェア(daemon)が動いていて,どういう「待ち受け」をしているか推測してみよ.

* サービス要求があったときに起動されるソフトウェア [#w8a39d62]
常にバックグラウンドでソフトを動かしていることには次のような利点と欠点がある.
-- すぐ反応できる(利点)
-- メモリや CPU をそれなりに消費する(欠点)

そこで,「たまに必要な時があるが特に迅速なレスポンスがなくともよい」というサービスについては「呼ばれてから起動する」というように設定しておくと無駄がない.
こうした用途に使われるのが「スーパサーバ」"inetd" ((知らない? ならばすぐマニュアルをみよう. マニュアルをすぐ見ることは unix では「よいこと」とされる))である.
inetd だけを立ち上げておけば,必要に応じて呼ばれたソフトウェアを起動して接続してくれるのだ.
ただし,inetd はその「便利さ」ゆえにセキュリティ的な緩さをもたらしやすいため,最近はデフォルトでは動いていないことが多いので,動かす際には明示的に設定しないといけないことに注意しよう.

** inetd を使うには [#e36b7cc1]

inetd を使うには,
++ /etc/inetd.conf で呼ばれたら立ち上がるソフトウェアの設定をする.
++ inetd がそもそも立ち上がっていないならば立ち上げる.
++ 外から接続が必要なソフトの場合は,接続許可を出しておく.

という段階を踏めばよい.
以下,説明しよう.

** inetd を使うには: /etc/inetd.conf の書き換え [#b5379e49]
// 黒本の p.400- を見ると丁寧に書いてある.

/etc/inetd.conf を見ると実例が書かれコメントアウトされているので,おおよそはわかるだろう.
7項目ある内容を大ざっぱに述べると,左から
++ サービス名:  /etc/services に書かれているものと一致しないといけない. inetd はservices の情報を使う.
++ ソケットタイプ: 通常は TCP ならば stream, UDP ならば dgram だ.
++ プロトコル: 通常は TCP か UDP だ. TCP はやり取りをする通信に,UDP は繋ぎっ放しの通信に向いているぞ.
++ 接続してからの inetd の挙動: 通常は TCP ならば nowait で UDP ならば wait だ. nowait には nowait/5 などとすると同時接続数を(例えばこの場合は 5までに)制限できる.
++ 立ち上げる deamon の実行権限: セキュリティを考えて特殊なユーザの権限にすることが最近は流行りだ.とりあえず root にしておけばセキュリティ以外の問題はあまり起らないが…
++ 立ち上げる deamon のpath: ソフトの在処. internal というのは inetd 自身が提供できるサービスだ.
++ 立ち上げる deamon のコマンド: コマンドラインオプションなんかも書ける.

となっている.

なお,既に inetd が動いている状態で /etc/inetd.conf を書き換えた場合は,
  kill -HUP (inetd のpid)
とすれば inetd.conf を読み直してくれる.

*** 実習 [#x10181d6]
試しに,ネットワークで接続して「今日の名言を聞せてくれる」サービスを実現してみよう(^-^)
それには,サービスを要求されたら「名言を出力する」プログラムを立ち上げるだけで良い.
そうしたプログラムには fortune というものが知られているので,これがコマンドとしてがインストールされている((インストールされていなければ,sysinstall → Configure → Distributions → games でインストールせよ))ことを確認しよう.

その後,/etc/inetd.conf に
  qotd stream tcp nowait root /usr/games/fortune fortune
と書き加えればこの準備は終り(間は「タブ」).
(全部で 7項目. 項目間はタブで区切る)
と書き加えればこの準備は終り.

** inetd を使うには: inetd の立ち上げ [#macde73e]

起動時にいつも動くようにしておくには, /etc/rc.conf に
  inetd_enable="YES"
と書いておけばよい.
手動で立ち上げるには,root で
  /etc/rc.d/inetd start
とすればよい.

*** 実習 [#zd573706]
inetd が動くようにしよう.

** inetd を使うには: 外からの接続許可 [#n3326344]

セキュリティ対策として,TCP wrappers による「接続許可」制度が FreeBSD には導入されている.
inetd はデフォルトではこの接続許可制度を利用する((利用しないようにもできる)).

具体的には,この許可がどうなっているかは /etc/hosts.allow で記述される.
記述は見れば分かるが,
  プログラム名 : 接続してくるマシン名 : 許可/不許可
というようになっており,上の行から「該当するかどうか」を調べていくようになっている.
そして,「最初に該当した設定」が有効になる仕組みだ((より詳しくは "jman hosts_access" としてマニュアルを参照せよ)).

たぶん,皆の初期設定では最初の方に
  ALL : ALL : allow
と書いてあるだろうから,まずはいじらないでおこう.
この場合,何でも無制限で接続されることになるので,計算機室では問題ないが,外部向けサーバでは注意すべき点の一つである.

*** 実習 [#c4ea0835]
  telnet localhost 17
と自分のマシンに接続してみて,今日の名言が出力されるか見よ.
次に,少なくとも自分でない他二人のマシンに対して同様に
 telnet (相手マシン名) 17
としてきちんと名言が出力されるか見よ.

次に,/etc/hosts.allow の ALL : ALL : allow よりも前に
  ALL : localhost : allow
  fortune : ALL : deny
という二行を書き込んでから((fortune ではなくて qotd と書きそうになるがそうではないので注意すること)),inetd を一旦止めて,そして動かそう(("kill -HUP  (inetd の pid)" でも良さそうだが,念の為)).
それには
  /etc/rc.d/inetd stop; /etc/rc.d/inetd start
とすればよい.

それから,自分のマシンに接続してみて名言が出力されること,他のマシンから接続して貰って確かにサービスが外からは受けられないことを確認せよ.

* 定期的に起動されるソフトウェア [#x20f09f3]

上に述べた「いつも動いている」「呼ばれたら動くように待機している」というソフトウェアの他に,「定期的に動く」ソフトウェアがある.
システムの調査や update など,定期的に実行した方が良いものが相当する.

具体的な仕組みとしては inetd に良く似ており,定期的にそれらのソフトを起動する "cron" daemon があり, cron が設定に従って様々なソフトウェアを起動するようになっている.

** cron [#n8329585]

起動後は cron は一分毎に目覚め,その度に設定ファイルをチェックしてから設定に従って条件にあうソフトウェアを動かすようになっている.
よって,設定ファイルを書き換えた後にその結果を反映させるための特別な操作は必要ない…はずだが,そうでない場合もあるようだ((つまり, 設定ファイルを書き換えたらやっぱり "kill -HUP (cron の pid)" としたほうがよい)).

cron に作業をさせるための設定ファイルは一般に crontab と呼ばれ,次のような二種類がある.
++ /var/cron/tabs/ユーザ名 … 直接エディタでいじらずに,"crontab -e" とコマンドを起動して編集する.
このコマンド "crontab" ((混同しやすいが,crontab というコマンドもあるのだ))については "jman crontab" でマニュアルを読むことができる.
また,ファイル形式については((/etc/crontab が良いサンプルになる)) "jman 5 crontab" とするとマニュアルがひける. ただし,ユーザ名(第6項目)は不要.
ただし,この設定ファイルに書いた内容が実行されるかどうかはそのユーザに cron の実行権限があるかどうかに依存する.
おおざっぱには,/var/cron/allow ファイルにそのユーザ名が書いてあり,/var/cron/deny ファイルにそのユーザ名が無ければよい.
++ /etc/crontab … システム用. 直接エディタで編集する.

*** 実習 [#p9bcb06f]
cron を使ってみよう.

まず,通常ユーザでも cron が使えるように,/var/cron/allow を設定せよ.
具体的には,ユーザ名のみを書いた行が /var/cron/allow にあればよい(その行にスペースやタブなど,ユーザ名以外の文字が入っていてはいけない).

そうしたら通常ユーザで cron を使ってみよう.
  crontab -e 
として,適当な内容を登録してみるということだ. 例えば,
  */1 * * * * tail /var/log/messages >> 適当なファイル名
(全部で6項目. 項目間はタブで区切る. 最後の項目 "tail ... " の要素間はスペースで区切っている)
(全部で6項目. 項目間はタブで区切る. 最後の項目 "tail ... " は "tail" コマンドを使ったコマンド文なので,この中身の要素間はスペースで区切っている)
などと登録しておけば,messages の最後の 10行が 1分毎に追加され記録されることになる.
登録できたかどうか
  crontab -l 
とすればわかる.

で,実際に動いているかどうかは,(rootで) /var/log/cron を読めば cron のログが分かるので判定できる.
うまくいかない場合は,ログをみて登録に問題がないかよくみよう.
また,登録が有効になっていないというような場合は,cron に対して kill -HUP をかけよう.

(うまくいったあとは再び crontab -e などを使って登録を外し, 念の為に cron に対して kill -HUP をかけておくこと)

** periodic [#we45ceec]

定期的に行われるシステム作業のうち特に典型的なものは /etc/periodic 以下におかれ,periodic コマンドで動かされる.
この periodic コマンドは cron でよばれるようになっている((/etc/crontab にperiodic を呼んでいる部分があるはずだ)).
periodic コマンドの設定は /etc/periodic.conf でなされる. 
そのデフォルト値は /etc/defaults/periodic.conf に書かれている.

** newsyslog [#y66b6442]

newsyslog も cron から呼び出されることを想定しているソフトウェアで,様々なソフトウェアのログファイルの保全を行うものである.
具体的には,現在のログファイルを名前を変えて保存して,新しいファイルを用意する作業を行う.
設定は /etc/newsyslog.conf で行われる.
この設定を適切に行なっておかないと,ログファイルが大きくなりすぎてハードディスクが溢れたりする.

*** 実習 [#q8c6ee6e]
/etc/newsyslog.conf を読んで,今の時点でどのようなログファイルがどのように保全されているか調べよ.

* レポート [#i2b13dee]
本日行った作業の報告,および今動いている daemon について,各々どのような daemon なのか調べてリストにしての報告を,furihata あっと cmc.osaka-u.ac.jp にメールで送付せよ.
もちろん各自の「所属,学年,学籍番号,氏名」を書くのを忘れないように.