まず、対象となるパーティションを DOS パーティションとしてフォーマットして、 そのパーティション上に Windows スワップファイルを作成します。しかし、まだ Windows は起動しないでください(あとで圧縮がよく効くように、この時点では スワップファイルを空にしておいてください)。
Linux を起動して、上記パーティションをファイルとして保存します。たとえば、 パーティションが /dev/hda8 であるとすると、以下の ようにします。
dd if=/dev/hda8 of=/etc/dosswap |
DOS スワップファイルを圧縮します。ほぼすべて 0 が並んでいるので、圧縮は非常に よく効きます。
gzip -9 /etc/dosswap |
/etc/rc ファイルに次のような行を加えて、Linux 上に スワップスペースを準備し、インストールします。
注意: XXXXX の部分には、スワップパーティションのブロック数が 入ります。
mkswap /dev/hda8 XXXXX swapon -av |
/etc/fstab ファイルにこのスワップパーティションの エントリを加えるのを忘れないでください。
お使いの init および reboot パッケージが /etc/brc か /sbin/brc をサポートしている場合、次の行を /etc/brc に付け加えてください。サポートしていない時は、DOS もしくは OS/2 をブートする場合でスワップパーティションを DOS/Windows バージョンに 戻したい場合に、下記を手動で入力してください。
swapoff -av zcat /etc/dosswap.gz | dd of=/dev/hda8 bs=1k count=100 |
注意: 上記は、最初の 100 ブロックをパーティション上に書き戻すだけです。 わたしは、経験上これで充分だと思っています。
>> この方法の長所と短所
長所:かなりのディスクスペースを節約できること。
短所:ステップ 5 を自動化できない場合、毎回手動で入力しなければならないので、 リブートが 1 ナノ秒遅れてしまうこと。:-)
ここでは、わたしがこれまで何度か使ったトリックを紹介します。
削除してしまったテキストファイルをなんとかして復活させる方法。
テキストファイル、たとえばメールや深夜のプログラミング作業の成果といった ものを誤って削除してしまったとしても、諦めてしまうのは早計です。 ファイルが一旦ディスクに書き込まれていた場合、すなわち、だいたい 30 秒以上 そこにあった場合は、その内容はまだディスクパーティションに残っているかも しれません。
grep コマンドを使って、生のディスクパーティション (raw disk partition)を検索し、ファイルの中身を探すことができます。
たとえば、最近わたしは誤ってあるメールを削除してしまいました。その際、まず わたしはメールが存在していたパーティションの内容を変更してしまうような作業を すべて急遽取りやめました。この時は、ファイルを保存したり、プログラムを コンパイルしたりしないようにしました。それ以外にも、実際にシステムをシングル ユーザモードに落として、そのファイルシステムを umount したこともありました。
次に、わたしは、対象となるディスクパーティションに egrep コマンドをかけました。その際、削除してしまったメールは /usr/local/home/michael/ に置かれていたので、 df コマンドの出力から、それが /dev/hdb5 にあることが分かりました。
sputnik3:~ % df Filesystem 1024-blocks Used Available Capacity Mounted on /dev/hda3 18621 9759 7901 55% / /dev/hdb3 308852 258443 34458 88% /usr /dev/hdb5 466896 407062 35720 92% /usr/local sputnik3:~ % su Password: [michael@sputnik3 michael]# egrep -50 'ftp.+COL' /dev/hdb5 > /tmp/x |
わたしは、ディスクパーティションをいじる際は極端に慎重になるので、ここでも リターンキーを押す前に、一旦間をおいて、コマンドの構文が正確かどうか確認しま した。この場合、メールには "ftp" という単語が含まれていて、その後に "COL" という単語で始まる文章が続いていました。メールのメッセージは 20 行くらいだった ので、-50 を使って該当する文章の前後すべてのテキストを 取得するようにしました。以前は、-3000 を使って、ソースコード のすべての行を取得できるようにしたこともありす。また、ここでは、egrep の出力を別のディスクパーティションにリダイレクトしています。 これは、探しているメールが、egrep の出力で上書きされて しまうことを防止するためです。
つづいて、strings を使って、取得した出力を検査して みました。
strings /tmp/x | less |
思った通り、メールはその中に入っていました。
この方法は、ディスクスペースの全部または一部がすでに上書きされているような 場合には、成功しないかもしれません。
このトリックが有効なのは、おそらく一人でシステムを使っている場合だけかもしれ ません。複数のユーザがいて、ディスクが頻繁に書き換えられる場合だと、削除 したファイルが置かれていた空間はすでに上書きされてしまっているかもしれません。 それに、たいてのユーザは、ファイルを復旧する必要があるときでも、マシンを勝手に 独り占めするようなことはできません。
わたしの自宅のシステムでは、過去数年で 3 度ほど、数日分の成果を間違って捨てて しまった際に、このトリックが役立ちました。こうした作業を通じて自分でもたいへん 進歩したと思っている点は、フロッピーに作業のバックアップを取っておくように なったことです。おかげで、このトリックを使う機会は随分減りました。
Immutable フラグを使おう。
システムのインストールと設定が済んだら、すぐに /bin、 /sbin、/usr/bin、/usr/sbin、/usr/lib (その他、およそ 必要そうな場所) にいって、どんどん chattr +i コマンドを実行 します。そして、root になって、カーネルファイルにもそのコマンドを実行 してください。次に、mkdir /etc/.dist/ を実行して、/etc 以下にある全ファイルをそのディレクトリにコピーします (わたしは、一旦 /tmp/etcdist.tar を作ることで、コピーが ループするのを防いでいます。/etc/.dist.tar.gz を 作るというのでもいいでしょう)。そして、それらのファイルも immutable にします。
このようにしておくと、root でログインした際でも起こりうるダメージを最小限に 食い止められます。リダイレクション操作を誤ってファイルを上書きすることが なくなりますし、rm -fr コマンドで間違ってスペースを 入れてしまいシステムを不安定にしてしまうこともなくなります(その場合でも、 データにはかなりのダメージが及ぶかもしれませんが、ライブラリとバイナリの 安全性は向上します)。
また、この作業によりセキュリティ全般が強化され、サービスを停止させるような 攻撃が不可能もしくはより困難になります(そうした攻撃の多くは、SUID された プログラムの挙動を悪用してファイルを上書きする方法をとっていますが、 そうした SUID されたプログラムは本来勝手なシェルコマンドの実行を許すもの ではないからです)。
この作業による唯一の短所は、様々なシステムコマンドをビルドして、 make install する際に不便が生じるという点です。 つまり、make install する場合でも、ファイルを上書き できなくなってしまいます。あらかじめ Makefile を読んで、 上書きされることになるファイル(およびファイルがインストールされるディレクトリ) に対して chattr -i を実行するのを忘れると、make が失敗 してしまいます。そうした場合は、chattr を実行し、 再度 make してください。また、その機会を利用して、古いバイナリやライブラリ などを .old/ ディレクトリに移動させたり、リネームしたり、 tar でまとめておいたりするといいかもしれません。
新しいモノはみんな /usr/local か /usr/local/'hostname' から始めよう。
お使いのディストリビューションの /usr/local 以下が 空になっているなら、自分で /usr/local/src や /usr/local/bin などを作成して使いましょう。 お使いのディストリビューションの /usr/local 以下に すでにファイルツリーがある場合は、mkdir /usr/local/'hostname' を実行した上で、'wheel' グループに書き込み権限(+w) を与えましょう(わたしはさらに、SUID および SGID することで、wheel グループの 個々のメンバだけがそこにファイルを置け、それらの全ファイルが wheel グループに 属するようにしています)。
これからは、いつも!いつも!いつも!新しいパッケージを /usr/local/src/.from/取得場所の名前($WHERE_I_GOT_IT)/ に 置いて、/usr/local/src (もしくは ... /$HOSTNAME/src) 以下でコンパイルするようにしましょう。 もし「どうしても」/bin や /usr/bin 等にインストールしなければならないプログラムであるなら、/usr/local/ 以下の階層から必要な場所にシンボリックリンクを張るようにしま しょう。
こうした作業は面倒ではありますが、これによって、ディストリビューションの メディア(最近は CD が一般的です)から全体を再インストールする際に、 バックアップやリストアすべき部分と、再インストールすべき部分を分けやすく なります。また、/usr/local/.from ディレクトリを使う ことで、ソースをどこから取ってきたかを不完全ながら記録しておくことが できるので、パッケージを更新するときに便利ですし、セキュリティ関係の アナウンスを追いかけるときには非常に重要な情報になります。
自宅のシステムのひとつ(今これを書いているマシン)を使い始めた当時、 わたしはまだこうした方針を実行していませんでした。それゆえ、 「インストールした当初の」状態と現在の状態とがどれだけ違うか未だに よく分かっていません。マシンのシステム設定はほとんどいじっておらず、 これを使っているのは自分だけであるにも関わらず、そんな状況なのです。
それにひきかえ、わたしが職場(システム管理者の役をやらされていた 頃です)で設置したシステムは、すべて上記の方法で設定しました。 それらのマシンは、契約先の SE や情報関係の様々なひとびとによって 管理されてきましたが、今でもわたしは、最初にインストールと設定を した後に組み入れられたパッケージがどれなのかをつぶさに理解しています。
Linux Gazette の issue 12 に掲載されている 2c tips (訳注:原文は、 こちらです。なお、この Tips は、Linux Gazette issue 13 に掲載されています。 山口さん、情報提供ありがとうございました。) で、ちょっと難しすぎるか不必要と思われる手順が紹介されていることに 気付きました。方法はいろいろあるわけなので、わたしからもその手順を紹介します。
#!/bin/sh # lowerit # カレントディレクトリの全ファイル名を小文字に変換するスクリプト # 通常ファイルだけを対象とする --ディレクトリ名は変更しない # 既存のファイルを上書きする前に、確認を求める for x in `ls` do if [ ! -f $x ]; then continue fi lc=`echo $x | tr '[A-Z]' '[a-z]'` if [ $lc != $x ]; then mv -i $x $lc fi done |
ん〜、長すぎます。わたしなら、こういうふうには書きません。むしろ、 次のコマンドを使います。
for i in * ; do [ -f $i ] && mv -i $i `echo $i | tr '[A-Z]' '[a-z]'`; done; |
これなら、コマンドラインで出来ます。
この投稿者は、彼が使っている方法を分かり易いスクリプトにしたと いっていますが(下記参照)、ちょっと違うと思う。
次の tips は、ユーザの追加と削除についてです。Geoff は上手くやっています が、最後の手順がよくない。リブート? 彼がユーザの削除のたびにリブート していないことを望みます。最初のふたつの手順で充分です。そのユーザがどんな プロセスを走らせているのでしょうか? IRC ロボットでしょうか? そうした プロセスは次のコマンドで簡単に kill できます。
kill -9 `ps -aux |grep ^<username> |tr -s " " |cut -d " " -f2` |
たとえば、ユーザ名が foo なら、以下のようになります。
kill -9 `ps -aux |grep ^foo |tr -s " " |cut -d " " -f2` |
これで充分です。忘れてた root パスワードが必要になりますが。
Linux Gazette で紹介されてる解決法は最も汎用性がありますが、一番簡単な方法と いうわけじゃありません。LILO や loadlin を使っているなら、ブートパラメタとして "single" を入力して、ログイン手続きやパスワードなし でデフォルトシェルを直接起動できます。その状態でパスワードを変更するか削除した 上で、"init" を入力し、マルチユーザモードに 移行すればいいと思います。この場合、リブート回数は 1 回で済みます。そうでない と 2 回必要です。
Justin Dossey
ここでは、何も修正されていないオリジナルのソースを使います。まず、sendmail の ソースコードを入手します。わたしは、version 8.9.0 を取ってきました。これは、 お気づきかと思いますが、安定版ではありません。取得先は、 ftp.sendmail.org:/pub/sendmail/sendmail.8.9.0.tar.gz でした。
これは 1 メガ前後あり、現在わたしは 8.7.6 を使っていることを考慮すると、 この作業はなかなか大変です。上手くいけばメールのやりとりができますが、 そうでないと、メールなしでは HOWTO の新版を出せなくなってしまいます。:)
ソースを落としたら、解凍します。解凍すると、カレントディレクトリに sendmail-8.9.0 というサブディレクトリが作成されます。その ディレクトリに移動して、README と README_NOTES を読みましょう(そして、開発者たちが達成した更新結果に 驚愕しましょう)。次に、src ディレクトリに移動します。 作業のほとんどは、ここで行います。
簡単な注意: sendmail は、コンパクトでパワフルな非常に良くできたプログラムです。 sendmail のバイナリは、5x86 133MHx の CPU と 32M バイト RAM のわたしの 環境でも 5 分以下でコンパイルできました。(設定を除いた)コンパイルと インストール全体で、15 分以下です!
わたしは普段自分のシステム上で BIND を動かしていないので、次の行は、
# ifndef NAMED_BIND # define NAMED_BIND 1 /* use Berkeley Internet Domain Server */ # endif |
1 を 0 に変更し、以下のようにしました。
# ifndef NAMED_BIND # define NAMED_BIND 0 /* use Berkeley Internet Domain Server */ # endif |
Debian 1.3.1 の場合、デフォルトで db.h は、sendmail で必要とされる /usr/include ではなく、/usr/include/db にインストールされます。それゆえ、src、mailstats、 makemap、 praliases、 rmail、 smrsh のそれぞれのディレクトリに移動して、次のコマンドを実行して ください。
./Build -I/usr/include/db |
以上が済んだら、cd .. を実行し、make install と打ってください。これで sendmail version 8.9.0 が インストールされます! もちろんこれは、自分用の設定ファイルを既にもっている 場合です。わたしは majordomo を使ったフリーメーリングリストをホストしている ので、すべてをスムースに稼働させるために、次の行を /etc/sendmail.cf に付け加える必要がありました。
O DontBlameSendmail=forwardfileinunsafedirpath, forwardfileinunsafedirpathsafe |
sendmail 8.9.0 は、ディレクトリ配置やファイルパーミッションの設定を最近細かく チェックするようになっているので、エイリアスとなっているディレクトリや ファイル、もしくはグループでの書き込み権限や自由な書き込み権限が付けられた .forward ファイルについて sendmail から文句が出るかも しれません。こうした細かなチェック機能を停止させることはよい考えではありま せんが、わたしはシングルユーザでコンソールを使って作業するだけなので、 チェック機能停止が小さなセキュリティホールとなったとしても大丈夫だろうと 思っています。そのあたりは、ご自分の環境にあわせて判断してください。YMMV
/README.'hostname' か /etc/README.'hostname' のどちらか一方もしくは両方を作って、それを管理すること [ あるいは、/usr/local/etc/README.'hostname' でもいいで しょう 〜管理人]
システム管理を始めたその日から、必ずオンラインのログファイルに記録を 付けるようにしましょう。root の /bash_logout に "vi /README.$(hostname)" という 一行を入れておくこともできます。あるいは、次のような su もしくは sudo スクリプトを書いておいてもよいでしょう。
function exit \ { unset exit; exit; \ cat ~/tmp/session.$(date +%y%m%d) \ >> /README.$(hostname) && \ vi /README.$(hostname) } script -a ~/tmp/session.$(date +%y%m%d) /bin/su.org - |
(入力履歴を記録するコマンドを使ってセッションログを取るとともに、関数を 作成して自動的にそのログに追加・更新がなされるようにしています)
わたし自身は、こうした自動化を方針として採用していません。これまで手動で 記録する習慣を守ってきました。ただ、自動化というのもアリかなと思っている だけです(ご覧のように、スクリプトやシェル関数を作ってみたりはしてるわけ です)。上記スクリプトで気になる点は、script コマンド が入っているところです。このコマンドのソースを取ってきて、(コマンド履歴の 記録を一時停止したり中止したり出来るような)コマンドラインパラメタを付け加え てから、これを使おうと考えています。
わたしの(今回の)最後の提案は、
root ユーザのパスは、'PATH=bin' とすべきである
ということです。root のパスにそれ以外を付け加えるべきではありません。 ルートの作業で使うコマンドは、/bin からのシンボリック リンクかエイリアス、もしくはシェル関数というかたちで提供するか、あるいは、 /bin にあるスクリプトかバイナリとするか、絶対パスを指定 するかのいずれかにすべきです。
こうしておけば、root 権限で作業をする人は、自分がどれほどバイナリを頼りに しているか(ときには、痛いほど)分かるはずです。マルチユーザのホストを管理する 賢明なシステム管理者なら、自分の /bin や /.*history ファイルを定期的に調べて、なんらかのパターンや抜け穴が ないかどうか探すようになるでしょう。
本当にヤル気のあるシステム管理者なら、自動化できる箇所を探し当て、 システムの妥当性を検査するプログラムを必要な場所に置くことで、root 権限が 必要な作業をいちいちしないで済むようにするでしょう (スクリプトによって機能を細かく調整できる、エディタや MTA その他の対話的な 巨大プログラムについては、透過的なファイルやデータファイルが利用されることに なるでしょう。たとえば、悪名高い vi の ./.exrc や emacs の ./.emacs、さらに面倒な $EXINIT および組み込みヘッダやフッタマクロといったものです)。 当然、そうしたコマンドは、次のように実行することもできます。
cp $data $some_users_home/tmp su -c $origcommand $whatever_switches cp $some_users_home/tmp $data |
(オプションや引数は、コマンドによって異なります)
自宅で利用する場合やユーザが自分だけという場合、後半部分での提案は大げさでは ありますが、マルチユーザシステムの管理者、特にインターネットに常時接続されて いる(ネット関連企業などの)システムの管理者の場合、これらは非常に有益な ポリシーであると思います。
xdm を起動するファイル(たいてい、/etc/rc/rc.6 か /etc/rc.local にあります)を開いて、xdm の起動セクション が次のような内容になるよう編集します。
/usr/bin/X11/xdm exec /usr/bin/X11/X -indirect hostname |
/usr/lib/X11/xdm/Xservers を開いて、ローカルマシン上の X サーバを起動させる行をコメントアウトします(すなわち、起動しないように します)。
マシンをリブートすると、ローカルマシン上の X サーバも、リモートマシンの X サーバも両方使えるようになります。
これを紹介するのは、わたしがなんとか自分自身のサブネットを設定して現在の 状態にもってくる際、すべての問題の解決に 2 週間ちかくかかったからです。
注意:古い SLS (1.1.1) を使う場合、理由はよく分かりませんが、xdm の設定行に -nodaemon という記述を入れたままにすることもできます。 ただし、これは、それ以降のバージョンには当てはまりません。