« 2009年8月 | トップページ | 2009年11月 »

セキュリティの小技(TCP/IP 編)

 FreeBSD のセキュリティ向上に役立つ… かもしれない(^^;小技を紹介します。

(10月に、試験を2つも受けなくてはならないことをすっかり忘れていて、急遽(きゅうきょ)、詰め込みモードに入ったので、しばらく縮小営業します… あと少しで、この FreeBSD 解説シリーズも終わるはずだったんですけど(^^;

 サーバをインターネットに公開しておくと、招かざるお客さんも、もれなくやってくるので(^^;、サーバのセキュリティを高めておくことが大切になります。

 そんな時に、ここで紹介する設定をやっておけば、多少はセキュリティ向上に役に立つかもしれません。
プライベートなサーバなら、お勧めの設定を全てやっておいてもいいですが、一般に広く公開しているサーバでは使えないワザもあるので、そのあたりは様子を見ながら、設定してみて下さい。)


 ちなみに、私が今回立てた Squid サーバは、ADSL ルータの内部にあるので、ここで紹介した設定は、まったくやってません(^-^;(^^;;ぉぃ。


● /etc/rc.conf で設定できるもの

 tcp_drop_synfin="YES"

 SYNFIN の両方を含んだ TCPパケットを、受け付けない(無視する)ようにします。

 こんなパケットは、当然ながらデータ送受信の役には立ちませんが、一方で、これにどう反応するかによって動いている OS の種類が特定できてしまうらしいので、安全のため、無視(無反応)を決め込んでもよいでしょう。

 ちなみに、TCP の処理には手間ひまがかかるため、これを設定しておくと、(実際に SYNFIN パケットが送られてくる環境では)CPU の負荷を下げるのにも役立つようです。

 icmp_drop_redirect="YES"

 ICMPリダイレクト要求を受け付けない(無視する)ようにします。

 インターネット上で問題が起きたため、正常に動いている別ルートに誘導してくれている、という可能性もなくはないですが、実際問題、アヤしいルートへと誘われている可能性の方が高いので、安全をとって無視してしまってもよいでしょう。

 icmp_log_redirect="YES"

 前述の ICMP のリダイレクト要求があったら、ログ(/var/log/messages)に記録します。

 log_in_vain="YES"

 開いていないポートにパケットが届いたら、ログ(/var/log/messages)に記録します。

 ただし、ポートスキャンDoS 攻撃を受けた場合、大量のログが出力されることがあるので、ネットワークの速度が飛躍的に向上した現在では、あまり使われない設定です。

 icmp_bmcastecho="NO"

 ブロードキャスト/マルチキャストされた ICMP に対し、応答を返さないようにします。
 (FreeBSD は、デフォルト"NO" になっています。)

 これは、悪意のある PC が、被害者のIPアドレスを騙って(かたって)、ブロードキャスト/マルチキャスト ICMP を送信し、その応答を被害者の PC に集中させて、身動きをとれなくする… という攻撃に利用されることがあるので、自分が加害者にならないよう、禁止("NO")にしておきます。


● /etc/sysctl.conf で設定できるもの

 /etc/sysctl.conf は、FreeBSD のカーネルの設定を変更するために使われる設定ファイルです。

 net.inet.tcp.log_in_vain=2
 net.inet.udp.log_in_vain=1

 開いていないポートにアクセスがあったら、ログ(/var/log/messages)に記録します。

 特に、tcp.log_in_vain=2 とすることで、/etc/rc.conf で log_in_vain="YES" としたときよりも多くのログを残すことができます。

 なお、「より多くのログが残る」ということは、当然、これも現在はやらない方がいい設定です(^^;;

 net.inet.tcp.blackhole=2
 net.inet.udp.blackhole=1

 開いていないポートにパケットが届いても、応答を返さないようにします。

 net.inet.tcp.blackhole の方は、ポートスキャンの対策になるとともに、前述の tcp_drop_synfin と同じ理由で、CPU 負荷を低くするのにも役立つはずです。

 一方で、net.inet.udp.blackhole については、ポートスキャンの対策には有効ですが、これを設定した場合、外部からの traceroute にも応答しなくなるので、一般に広く公開しているサーバでは、できるだけ使わない方がよいでしょう。

 net.inet.icmp.icmplim=200

 ポートスキャン、あるいは DoS 攻撃があった場合に、ログ(/var/log/messages)に記録を残します。

 もう少し詳しく言うと、開いていないポートにパケットが届いた場合、TCP/IP の約束では、パケットの送信元に ICMP の Unreachable メッセージ、または TCP の RST パケットを返すようになっています。

 しかし、広範囲のポートに対してポートスキャンを受けたような場合には、返すべき応答パケットの数が異常に増えるので(最悪の場合、自分が DoS 状態におちいってしまう(^^;)、net.inet.icmp.icmplim の設定値に達したところで、応答を返すのをやめてログに記録を残します

 なお、FreeBSD のデフォルトでは、上に挙げた例と同じ "200" に設定され、1秒間に 200 個以上、上記のような応答が発生したら、ログに記録するようになっています。

| | コメント (1) | トラックバック (0)

FreeBSD の操作を効率的に(tcsh:後編)

 では、先週宣言した通り、tcsh の説明の続きを… といきたいところですが、先週は、いろいろと不親切だったような気もするので、ちょっと戻って、まずは一般的な話から(^^;

■ 代表的なシェル

 現在、広く使われている(と思われる)シェルを、簡単に紹介しておきます。

(1) sh (Bourne Shell、ボーンシェル、ビーシェル)
 シェルスクリプトの実行に役立つ、多くの機能を備えた、近代シェルの先駆け。
 現在も、シェルスクリプトの解釈・実行用として、標準的に使われています。
 「Bourne」の由来は、作者の名前から。

(2) ash (Almquist Shell、アッシュ(?)、エーシェル(?))
 Bourne Shell の代用として作られたシェル。
 Bourne Shell よりもコンパクトで、処理が早いのが特徴。
 BSD系や、Debian系の Linux では、Bourne Shell 代わりに使われています。

(3) csh (C Shell、シーシェル)
 当初、BSD向けに開発され、その後、大流行したシェル。
 優れた操作機能を持ち、現在の対話的なシェルの手本となりました。
 名前の由来は、シェルスクリプトC言語風に書けることから。

(4) ksh (Korn Shell、コーンシェル)
 Bourne Shellcsh の「いいとこ取り」をしたシェル。
 商用(使うのにお金が必要な) UNIX でよく使われていた(らしいです)。
 「Korn」の由来は、作者の名前から。

(5) bash (Bourne Again Shell、バッシュ)
 Bourne Shell に、ライバルだった csh の機能を取り込んで作られたシェル。
 現在、Linux の標準シェル。
 名前の由来は、「Bourne Shell よ、再び(Again)!」…だそうです(^^)

(6) tcsh (TENEX Shell、テーシーシェル)
 csh をもとに、使い勝手を向上させたシェル。
 機能的には、tcshbash は、ほぼ互角です。

(7) zsh (ゼットシェル)
 ksh を基本に、bashtcsh の機能を取り込んだ、高機能シェル。
 個人的には、bash の方に似ている、と思うのですが…


 このうち、対話的シェルとして、現在人気があるのは、bashtcshzsh でしょうか。

 私は、対話的なシェルに tcsh、シェルスクリプトには ash (FreeBSD の /bin/sh) を使っています。


■ tcsh の機能(追加)

 前回、大切な機能が抜けていたので、追加します(^^;

● コマンド置換

 「`」(バッククォート。 日本語106キーボードでは、[Shift] を押しながら [@] を押すことで入力できます)で囲まれたコマンドを実行し、その出力結果で置き換えます。

 `cmdcmd を実行し、その出力
結果と置き換える

 例えば、次のように、あるコマンドを実行する際に、別のコマンドの実行結果が必要な場合があります。
 《 sshd のありかを調べる 》
$ which sshd[Enter]
/usr/sbin/ssh
 《 sshd で使用するライブラリを表示 》
$ ldd /usr/sbin/ssh[Enter]
/usr/sbin/sshd:
        libssh.so.4 => /usr/lib/libssh.so.4 (0x280b0000)
 ~~~

 《 syslogd のプロセスIDを調べる 》
# cat /var/run/syslog.pid[Enter]
434
 《 syslogd に設定ファイルを再読み込みさせる 》
# kill -HUP 434[Enter]
#  
 どちらの例もパイプは使えませんが、コマンド置換を使えば、1行で用件を済ませることができます。
 《 sshd で使用するライブラリを表示 》
$ ldd `which /usr/sbin/ssh`[Enter]
/usr/sbin/sshd:
        libssh.so.4 => /usr/lib/libssh.so.4 (0x280b0000)
 ~~~

 《 syslogd に設定ファイルを再読み込みさせる 》
# kill -HUP `cat /var/run/syslog.pid`[Enter]
#  
(「`」の中でも、補完機能が使えますよ~(^^)。)

● コマンドの連続実行

 これは、なんとなく裏ワザっぽい気がするのですが、一応、tcsh の正式な機能らしいので…

 cmd1 ; cmd2 cmd1cmd2 を連続実行
 cmd1 && cmd2 cmd1成功したら、
cmd2 を実行
 cmd1 || cmd2 cmd1失敗したら、
cmd2 を実行

 「成功」とか「失敗」という言葉が出てきましたが、UNIX 上で動くコマンドは、実行中に何かエラーが起きれば「失敗」、そうでなければ「成功」という結果を返すことになっています。


■ tcsh の設定

 tcsh は、とても多機能なことと、私が FreeBSD 上での作業をあまりやらないため(^^;、ここでは、簡単にさわりだけを紹介します。

 tcsh について、もっと知りたい、という方は、マニュアルページを読んでみて下さい。

 ◆ FreeBSD 日本語マニュアル検索: http://www.jp.freebsd.org/man-jp/search.html

 (「日本語マニュアル RELEASE :」の選択欄で、「7.2-RELEASE-K」を選ぶのを忘れずに)


tcsh の設定ファイルたち

 tcsh には、たくさんの設定ファイルがあります。
 主なものとしては…

 (1) /etc/csh.cshrc
 (2) /etc/csh.login
 (3) ~/.tcshrc (なければ ~/.cshrc)
 (4) ~/.login
 (5) /etc/csh.logout
 (6) ~/.logout

 …があります。

 ただし、設定ファイルごとに、読み込まれる条件と順番が決まっていて、

 ○ ログイン時
  /etc/csh.cshrc
  /etc/csh.login
  ~/.tcshrc (なければ ~/.cshrc)
  ~/.login

 ○ シェル起動時(ログイン時以外
  /etc/csh.cshrc
  ~/.tcshrc (なければ ~/.cshrc)

 ○ ログアウト時
  /etc/csh.logout
  ~/.logout

 …というルールになっています。

 /etc ディレクトリに置かれている設定ファイルは、FreeBSD 全体に関係する設定ファイルなので、通常は変更せず、カスタマイズする場合はユーザのホームディレクトリにある設定ファイルを変更します。

 普通は、~/.tcshrc をカスタマイズすれば十分なので、このファイルについて説明します。


■ .tcshrc の設定

 FreeBSD では、すでに ~/.cshrc が準備されているので、これを ~/.tcshrc という名前でコピーして、それを編集するのが一番楽でしょう。
 《 ホームディレクトリに移動 》
$ cd[Enter]
 《 ファイルの一覧を表示 》
$ ll[Enter]
total 16
-rw-r--r--  1 violet  violet  758 Sep  1 15:55 .cshrc
-rw-r--r--  1 violet  violet  258 Sep  1 15:55 .login
-rw-r--r--  1 violet  violet  167 Sep  1 15:55 .login_conf
-rw-------  1 violet  violet  379 Sep  1 15:55 .mail_aliases
-rw-r--r--  1 violet  violet  339 Sep  1 15:55 .mailrc
-rw-r--r--  1 violet  violet  773 Sep  1 15:55 .profile
-rw-------  1 violet  violet  284 Sep  1 15:55 .rhosts
-rw-r--r--  1 violet  violet  980 Sep  1 15:55 .shrc
 《 .cshrc を .tcshrc の名前でコピー 》
$ cp .cshrc .tcshrc[Enter]
 《 ファイルの一覧を表示 》
$ ll[Enter]
total 18
-rw-r--r--  1 violet  violet  758 Sep  1 20:00 .cshrc
-rw-r--r--  1 violet  violet  258 Sep  1 20:00 .login
-rw-r--r--  1 violet  violet  167 Sep  1 20:00 .login_conf
-rw-------  1 violet  violet  379 Sep  1 20:00 .mail_aliases
-rw-r--r--  1 violet  violet  339 Sep  1 20:00 .mailrc
-rw-r--r--  1 violet  violet  773 Sep  1 20:00 .profile
-rw-------  1 violet  violet  284 Sep  1 20:00 .rhosts
-rw-r--r--  1 violet  violet  980 Sep  1 20:00 .shrc
-rw-r--r--  1 violet  violet  758 Sep  9 20:09 .tcshrc ← これ
 《 .tcshrc を編集 》
$ vi .tcshrc[Enter]

 以下は、私が一般ユーザのときに使っている~/.tcshrc です。
 (ライトユーザなので、大した設定は、していませんが…(^^;;;

 赤字が、もとのファイルから変更した部分です。
# $FreeBSD: src/share/skel/dot.cshrc,v 1.14.8.1 2009/04/15 03:14:26 kensmith Exp $
#
# .cshrc - csh resource script, read at beginning of execution by each shell
#
# see also csh(1), environ(7).
#

alias h         history 25
alias j         jobs -l
alias la        ls -a
alias lf        ls -FA
alias ll        ls -lA

alias ls        ls-F
alias vim       jvim3
alias less      jless -e -c -~ --

# A righteous umask
umask 22

set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)

#setenv EDITOR  vi
setenv  EDITOR  jvim3
#setenv PAGER   more
setenv  PAGER   "jless -e -c -~ --"
setenv  BLOCKSIZE       K

#setenv LANG    C
setenv  LC_CTYPE        ja_JP.eucJP

if ($?prompt) then
        # An interactive shell -- set some stuff up
        set filec
        set history = 100
        set savehist = 100
        set mail = (/var/mail/$USER)
        if ( $?tcsh ) then
                bindkey "^W" backward-delete-word
                bindkey -k up history-search-backward
                bindkey -k down history-search-forward
                set zltn = `set | grep tty | cut -f 2 | cut -c 4-5`
                set prompt = "[%{^[[34m%}%m($zltn):%{^[[35m%}%n%{^[[0m%}]%/%# "
                unset zltn
                set histdup = erase
                set nobeep
        endif
endif
 ちなみに、root~/.tcshrc では、

29行目:#setenv LANG   C
  → setenv  LANG   C
43行目:set prompt = "[%{^[[34m%}%m($zltn):%{^[[35m%}%n%{^[[0m%}]%/%# "
  → set prompt = "[%{^[[34m%}%m($zltn):%{^[[0m%}/]%/%# "
45行目:set histdup = erase
  → #set histdup = erase

 の部分が違っています。


.tcshrc の解説

08行目~16行目:
 □ エイリアス(コマンドの別名)の設定です。

 エイリアスとは、(a) 長いコマンド名の入力を短縮する ためとか、(b) FreeBSD 本来のコマンドを、もっと便利なほかのコマンドに置き換えるため、といった目的で使われる機能です。

 なお、15行目と16行目は、実際に jvim3jless というプログラムがインストールされてないと、無意味です(^^;

14行目:alias ls   ls-F
 本来の ls (/bin/ls) の代わりに、tcsh組込みコマンド ls-F を実行します。

 ls-F を使うことにより、ディレクトリやシンボリックリンク、実行可能ファイルなどの区別が付けやすくなります

15行目:alias vim   jvim3
 jvim3 を、vim という短縮名で実行できるようにします

16行目:alias less   jless -e -c -~ --
 FreeBSD 本来の less (/usr/bin/less) の代わりに、jless を指定されたオプション付きで実行します。

 FreeBSD 本来の less を使いたい場合には、「/usr/bin/less」とフルパスで指定するか、頭に「\」を付けて「\less」 と実行すれば、本来の less を実行できます


 その他、便利そうなエイリアスの例として、

 ○ Windows でいう「ゴミ箱」機能らしきものを実現する:
  alias del   'mv \!* ~/.trush'

 などがあります。ただし、

 ○ alias rm   'mv \!* ~/.trush'
  や
 ○ alias rm   rm -i

 といった、削除コマンド「rm」をエイリアスに使う設定は、個人的にはお勧めしません


19行目:umask 22
 ファイルマスクの設定。

 細かい説明は省きますが(^^;;、要は umask を 22(8進数表記)に設定することで、新規に作成するファイルについては、自分以外の人は書き込みができないようにすることができます

21行目:set path = (/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin $HOME/bin)
 実行ファイル検索パス、通称パスの設定。

 これらのディレクトリ内にある実行ファイルの名前は、メモリ上に記憶され、パス指定なし(ファイル名を指定するだけ)で実行できるようになります。

 また、最後の「$HOME/bin」という おまじない(^^;の効果で、自分のホームディレクトリに bin ディレクトリを作り、その中に自作のプログラムを入れておけば、FreeBSD の標準コマンドと同じ感覚で使うことができます。
(ただし、~/bin に新しくプログラムを追加したら、rehash を実行することを忘れずに)


23行目~30行目:
 □ 環境変数の設定。

 あとから出てくるシェル変数とは異なり、ほかのプログラムから参照することができるので、tcsh などのシェルにより呼び出され、実行されるプログラムの振る舞いを決める(変える)ために使われます。

 なお、慣例として、環境変数の名前は大文字、シェル変数の名前は小文字とすることが多いです。

23行目:#setenv EDITOR  vi
24行目:setenv  EDITOR  jvim3

 標準で使うエディタを、FreeBSD 標準の vi から jvim3 に変更しています。
(何度も言いますが、jvim3 が実際にインストールされていないと、この設定も無意味ですよ~(^^;

25行目:#setenv PAGER   more
26行目:setenv  PAGER   "jless -e -c -~ --"

 標準で使うページャを、FreeBSD 標準の more から jless に変更しています。
(何度も言いますが、jless が実際にインストールされていないと…(以下、略))

 環境変数 EDITORPAGER は、いろいろなプログラムやスクリプトで利用されている環境変数なので、正しく設定しておきましよう。

27行目:setenv BLOCKSIZE   K
 ディスク情報を表示するプログラムが、ディスク容量を表示する際に使う「単位」を指定。

 「K」は kbyte 単位で表示させるため指定ですが、考えようによっては「M」(Mbyte) 単位で表示してくれたほうが見やすいかも。

29行目:#setenv LANG   C
30行目:setenv  LC_CTYPE   ja_JP.eucJP
 使用する言語の指定。

 環境変数 LC_TYPE の「値」を ja_JP.eucJP に設定することで、日本語 EUC を使うことを宣言しています

 もちろん、ターミナルエミュレータ側(Tera Term など)も EUC を使うよう、設定を合わせておく必要があります。

 なお、root の場合には、上記に追加して、環境変数 LANGC に設定することで、日本語 EUC を扱えるようにしながら、プログラム自体は、できるだけ標準(英語の設定)で動くようにしています


32行目~48行目:
 □ シェル変数 prompt が設定されているとき = (tcsh が)対話的シェルとして実行されたときに、有効になる部分です。

34行目~37行目:
 シェル変数の設定。

 シェル変数は、シェルだけにしか見えない(参照できない)ので、シェル自身(この場合は tcsh)の動作を決める(変える)のに使われます。

 ちなみに、ビーシェルBourne Shell)系では、シェル変数に「値」を設定する際、「=」の左右に「空白」があってはダメですが、csh系では「空白」があっても OK なので、一応、両者の違いとして覚えておくとよいと思います(^^)

34行目:set filec
 ファイル名とディレクトリ名の補完機能を有効にします

35行目:set history = 100
 コマンドライン履歴を、最大 100個まで、メモリ上に記憶します

36行目:set savehist = 100
 tcsh の終了時に、~/.history ファイルに、最大100個の履歴を保存します

37行目:set mail = (/var/mail/$USER)
 メールが届くディレクトリを指定すると、tcsh がメールが届いたことを教えてくれるはず… ですが、私のところでは、メール配送デーモンを動かしていない(※)ので、この設定は、無用の長物と化してます(^^;;;
/etc/rc.conf で、sendmail_enable="NONE" に設定してます


38行目~48行目:
 □ シェル変数 tcsh が設定されているとき = この設定ファイルが tcsh に読み込まれた場合のみ、有効になる部分。

 逆に言うと、この部分は csh では無視されるので、これをうまく使えば、cshtcsh で1つの設定ファイル(~/.cshrc)を共用するような使い方もできます。

39行目~41行目:
 tcsh の機能をキーに割り付ける指定

39行目:bindkey "^W" backward-delete-word
 [Ctrl][W] に、「1語削除」機能を割り付けます

40行目:bindkey -k up history-search-backward
 [↑] に、「入力された文字で始まる履歴を、新しいものから順に呼び出す」機能を割り付けます。

 …前回、[↑] は、単に履歴を古い方へさかのぼるだけです、と言ったのは嘘でしたm(_`_)m

41行目:bindkey -k down history-search-forward
 [↓] に、「入力された文字で始まる履歴を、新しい方へ戻る」機能を割り付けます


42行目~44行目:
 プロンプトの設定

42行目:set zltn = `set | grep tty | cut -f 2 | cut -c 4-5`
 前準備として、シェル変数 zltn に、ログインしている端末名の後ろ2文字(4文字目と5文字目)を代入します。
 …さっそく、コマンド置換が活躍してますね(^^)

 もう少し説明しておくと、端末名は、シェル変数 tty に「値」として自動的に設定され、ログインする端末に応じて、
コンソールの場合: ttyv0, ttyv1, ttyv2, ...
・ネットワーク経由の場合: ttyp0, ttyp1, ttyp2, ...
 となるので、結局、zltn には「v0, v1, v2, ...」または「p0, p1, p2, ...」のうちの、どれか1つが設定されます。

43行目:set prompt = "[%{^[[34m%}%m($zltn):%{^[[35m%}%n%{^[[0m%}]%/%# "
 ここでプロンプトを設定しています。
 …ごちゃごちゃして分かりづらいので、エスケープシーケンスの部分に、蛍光マーカを引いておきました(^^;

 簡単に意味を説明すると、

  %{   エスケープシーケンスの始まり
  %}   エスケープシーケンスの終わり
  %m   ホスト名(のうち、最初の「.」の前まで) ⇒ thyme に置き換え
  %n   ユーザ名 ⇒ violet に置換え
  %/   カレントディレクトリのパス名を表示
  %#   プロンプト文字(一般ユーザは「>」、ルートは「#」)に置換え
  $zltn   シェル変数 zltn の「値」に置き換え

 となるので、これを設定したあとのプロンプトは、次のようになります。
[thyme(p0):violet]/home/violet>  

 ちなみに、エスケープシーケンスを調べるには、次のようなファイルを esc.pl の名前で作成し、
#! /usr/bin/perl

  foreach $i (30..37, 40..47, 5, 4, 1, 0) {
    print "\x1b[${i}m ^[[${i}m \x1b[0m\n";
  }

 《 perl に esc.pl を読み込ませて実行 》
$ perl esc.pl[Enter]
 あるいは、
 《 esc.pl を実行可能に設定した後、実行 》
$ chmod 755 esc.pl ; ./esc.pl[Enter]
 とすれば、カラフルなエスケープシーケンス画面に表示されます

 UNIX において、プロンプトは、個性を主張するのに最適な手段なので、tcsh のマニュアルを読んで、ぜひお気に入りのプロンプトを作ってみてください(^^)

44行目:unset zltn
 prompt を設定した後は、シェル変数 zltn は不要なので、(zltn に設定された「値」を消すのではなく)シェル変数 zltn ごと消去します


45行目、46行目:
 □ tcsh の動作を制御するシェル変数の設定

45行目:set histdup = erase
 履歴中にあるものと全く同じコマンドが再入力されたとき、最新の履歴だけを残し、古いものを削除erase)します。
 これにより、重複のない、たくさんの種類の履歴を残すことができます。

 なお、root の場合、全ての履歴を残すことに意義があるので、この設定はコメントアウトしています

46行目:set nobeep
 ビープ音を一切鳴らしません


 また、これ以外に設定しておいた方がよいかもしれない、tcsh 用のシェル変数を紹介しておきます。

 ○ set ignoreeof
 [Ctrl][D] は、ディレクトリ名/ファイル名の補完候補を表示する際に使うキー操作ですが、何も文字が入力されていないときに [Ctrl][D] を押すと、シェルが終了し、自動的にログアウトしてしまいます
 set ignoreeof は、何も文字を入力していない時に [Ctrl][D] を押しても、ログアウトしないようにする設定です

 ○ set noclobber
 リダイレクトによるファイルの上書きを禁止します
 本当に上書きしたいときには、「!」を使って、「cmd >! file」などとします。

 ○ set correct = all
 コマンドラインの間違いを直してくれます。
 …個人的には、うるさく感じるので、使ってませんが(^^;

.tcshrc の設定を tcsh に反映させる

 ~/.tcshrc を変更したら、ホームディレクトリで
 《 指定されたファイルを読み込んで、解釈・実行する 》
$ source .tcshrc[Enter]
$  
 とすれば、~/.tcshrc の設定内容が tcsh に反映されます。

(注:環境変数あるいはシェル変数を「設定しない」ことにした場合には、「unsetenv」あるいは「unset」により、環境変数あるいはシェル変数を手動で消してあげる必要があります)


.login.logout の設定

 ~/.login~/.logout には、それぞれログイン時とログアウト時に実行したいコマンドを書きます。

 FreeBSD の場合、~/.login には、「今日のひとこと」を表示するプログラムを実行するよう、設定されています。
(FreeBSD のインストール時に、game をインストールしていないと、実行されないようになってますが…)

 一方の ~/.logout は、ファイル自体が準備されていませんが、例えば
clear
 という内容の ~/.logout を作成すれば、コンソールからログアウトすると同時に、それまで作業していた画面が消去されるので、セキュリティ的によいかもしれません(^^)

| | コメント (15) | トラックバック (1)

FreeBSD の操作を効率的に(tcsh:前編)

 シェルとは、使用する人(ユーザ)と OS の間の仲立ちをしてくれるプログラムのことです。

 OS は、プログラムから見て使いやすいように作られていますが、逆に人から見た場合には、とっつきにくくできているので(^^;シェルという、OS との橋渡しをしてくれるものが自然と必要になります。

 また、GUI が主流となっている現在では、シェルとは、OS の見た目と使い勝手を決めるもの、という とらえ方 もありますが、これもなかなか、いいところを突いていると思います(^^)


■ シェルを tcsh に設定する

 FreeBSD では、追加したばかりのユーザは、シェルが /bin/sh設定されているので、これを FreeBSD で、もっともおすすめのシェル、tcsh に変更します。
 《 ユーザ violet の、現在のシェルを確認 》
$ grep violet /etc/passwd[Enter]
violet:*:1021:1021:User &:/home/violet:/bin/sh ← /bin/sh
 《 選択できるシェルを表示 》
$ cat /etc/shells[Enter]
# $FreeBSD: src/etc/shells,v 1.5.34.1 2009/04/15 03:14:26 kensmith Exp $
#
# List of acceptable shells for chpass(1).
# Ftpd will not allow users to connect who are not using
# one of these shells.

/bin/sh
/bin/csh
/bin/tcsh ← これ
 《 シェルを tcsh に変更 》
$ chsh -s /bin/tcsh[Enter]
Password:《 violet のパスワードを入力 》[Enter]
chsh: user information updated
$  
 これで、一度ログオフして、再度ログインし直せば、tcsh がシェルとして起動します。
 《 ログアウト 》
$ exit[Enter]

 《 再度ログイン 》
login: violet[Enter]
Password:《 violet のパスワードを入力 》[Enter]
>   ← プロンプトが ">" に変わった
 ~~~
 《 シェル変数 "shell" を表示 》
> set | grep shell[Enter]
shell   /bin/tcsh
>  
(※ tcsh の一般ユーザのプロンプトは、本来「>」ですが、これ以降は(いままで通り)「$」で代用します。)

 ちなみに、root のシェルは変更してはいけない、という古くからの言い伝えがありますので、root のシェルは変更しないようにして下さい。

 とはいっても、一般ユーザでログインして、/usr/bin/su で root になった場合には、ユーザのシェルがそのまま引き継がれますし、(やむをえない事情で)root でログインしたときも、
 《 指定したプログラムを現在のシェルの代わりに実行 》
# exec tcsh[Enter]
 とすれば、tcsh を起動することができます。


■ tcsh の機能

 次に、よく使う tcsh の機能を紹介します。

コマンドライン編集

 当たり前だと思っている人も多いですが(^^;、tcsh では、コマンドラインに入力した文字の編集ができます!

[←], [→]カーソルを左右に移動
[BS]カーソルの左の文字を削除
[Ctrl]+[A]コマンドラインの先頭に移動
[Ctrl]+[E]コマンドラインの最後に移動

履歴ヒストリ

 以前に実行したコマンドを記憶しておき、あとから簡単に呼び出せるようにする機能です。

[↑]新しいものから順に、履歴を呼び出す
[↓]履歴を、新しい方へ戻る
[Esc][P]入力された文字で始まる履歴を、
新しいものから順に呼び出す
[Esc][N]入力された文字で始まる履歴を、
新しい方へ戻る
history履歴の一覧を表示
!nn番目の履歴を呼び出して、即実行

 ちょっと、試してみましょう。
 《 履歴の一覧を表示 》
$ history[Enter]
     1  20:00   cat /etc/passwd
     2  20:00   grep violet /etc/passwd
     3  20:00   cat /etc/shells
     4  20:00   chsh -s /bin/tcsh
     5  20:01   history
$  
 ここで、[↑] を押すごとに、「history」→「chsh -s /bin/tcsh」→「cat /etc/shells」→「grep violet /etc/passwd」→「cat /etc/passwd」が順番にコマンドラインに表示され、好きなときに [Enter] を押せば、表示されている履歴がコマンドとして実行されます(実行前に、コマンドラインを編集することもできます)。

 また、[↓] を押せば、「cat /etc/passwd」→「grep violet /etc/passwd」→「cat /etc/shells」→「chsh -s /bin/sh」→「history」→「(空白)」の順に、履歴を新しい方に向かって戻ることができます。

 履歴の中から、特定のものだけを探したい場合、
$ ca 
 と入力してから、[Esc][P] を押せば、「cat /etc/shells」→「cat /etc/passwd」と、「ca」で始まる履歴だけが表示されます。

 また、history コマンドで表示される番号を使って、コマンドを実行することもできます。
 《 2番の履歴を呼び出して再実行 》
$ !2[Enter]
grep violet /etc/passwd
violet:*:1021:1021:User &:/home/violet:/bin/tcsh
$  
補完

 ちょっと前は、「ファイル名のホカン」などど言ってもポカーンとされるだけでしたが、最近は「補完」という漢字を思い浮かべてくれる人が増えて、説明が楽になりました(^^;

 UNIX はディレクトリが深いので、この補完は、必須の機能です(^^)

[Tab]ディレクトリ名/ファイル名を補完
[Ctrl]+[D]ディレクトリ名/ファイル名の候補を表示

 補完の例: 下線部が、補完された文字を示します。
[Tab] による補完では、実際には行は変わらず、コマンドラインがどんどん右に伸びていきます。)
$ less /u[Tab] 《 補完実行 》
 
$ less /usr/  《 ディレクトリ名が補完された 》
 
$ less /usr/p[Tab]
 
$ less /usr/ports/ 
 
$ less /usr/ports/d[Tab] 
 
$ less /usr/ports/d  《 補完されない!? 》
 
$ less /usr/ports/d[Ctrl][D] 《 候補を表示 》
databases/ deskutils/ devel/     distfiles/ dns/
$ less /usr/ports/dn[Tab] 《 "n" を追加し、補完実行 》
 
$ less /usr/ports/dns/ 
 
$ less /usr/ports/dns/u[Tab]
 
$ less /usr/ports/dns/u  《 補完されない!? 》
 
$ less /usr/ports/dns/u[Ctrl][D] 《 候補を表示 》
udns/     unbound/  updatedd/
$ less /usr/ports/dns/un[Tab] 《 "n" を追加し、補完実行 》
 
$ less /usr/ports/dns/unbound/ 
 
$ less /usr/ports/dns/unbound/M[Tab]
 
$ less /usr/ports/dns/unbound/Makefile   《 ファイル名が補完された 》
 …これだけをみると、分かりづらい気がしますが、実際にやってみると、案外簡単です(^-^)

 補完では、ディレクトリ名が補完された場合には、最後に「/」が付き、ファイル名が補完された場合には、最後に「(空白)」が追加されます。

 ただし、最初の文字が一致するディレクトリ/ファイルが2個以上あるときは、途中までしか補完してくれないので、そのときは [Ctrl]+[D] で候補の一覧を表示し、ほかと区別が付くところまで文字を追加入力したあとで、再度 [Tab] を押して補完を実行ます。

 なお、何も文字が入力されていない状態で [Ctrl]+[D] を押すと、シェルが終了しログアウトしてしまうので、注意してください(^^;;

ワイルドカード展開

 複数のファイルをまとめて指定できる機能です。

  ?  任意の1文字にマッチ
  *  0文字以上の任意の文字にマッチ

 …言ってることが分かりませんね(^^;。 例を示します。
 《 /bin ディレクトリ内にあるファイルを表示 》
$ ls /bin[Enter]
[               df              link            pwd             sleep
cat             domainname      ln              rcp             stty
chflags         echo            ls              realpath        sync
chio            ed              mkdir           red             tcsh
chmod           expr            mv              rm              test
cp              getfacl         pax             rmail           unlink
csh             hostname        pgrep           rmdir           uuidgen
date            kenv            pkill           setfacl
dd              kill            ps              sh
 《 ワイルドカードの例1:末尾の「*」 》
$ ls /bin/ch*[Enter]
/bin/chflags    /bin/chio       /bin/chmod
 《 ワイルドカードの例2:先頭の「*」 》
$ ls /bin/*sh[Enter]
/bin/csh        /bin/sh         /bin/tcsh
 《 ワイルドカードの例3:途中の「*」 》
$ ls /bin/t*h[Enter]
/bin/tcsh
 《 ワイルドカードの例4:「?」 》
$ ls /bin/t?s?[Enter]
/bin/tcsh       /bin/test
$  
 また、tcsh の「*」は強力で、次のようなこともできます。
 《 複数ディレクトリで、ファイル内を検索 》
$ grep kqueue /usr/include/*/*/*[Enter]
/usr/include/cam/scsi/scsi_targetio.h: * of CCB completion through poll/select/kqueue and then calls
/usr/include/dev/firewire/firewirereg.h:#include &gh;sys/taskqueue.h<
/usr/include/dev/firewire/firewirereg.h:        struct taskqueue *taskqueue;
/usr/include/dev/firewire/fwohcivar.h:#include &gh;sys/taskqueue.h<
/usr/include/dev/usb/if_auereg.h:       struct usb_taskqueue    aue_taskqueue;
/usr/include/dev/usb/usb_ethersubr.h:struct usb_taskqueue {
 ~~~
$  
● ディレクトリの移動

 ディレクトリ間の移動は、UNIX の基本中の基本です。

cd dir指定されたディレクトリに移動。
dir を指定しないとホームディレクトリに移動
pushd dir カレントディレクトリを保存して、
指定されたディレクトリに移動
popd保存したディレクトリに戻る
dirspushd で保存されたディレクトリ一覧を表示
pwdカレントディレクトリのパスを表示

 また、ディレクトリの特殊な表現法として、

  /  ルートディレクトリ
  .  カレントディレクトリ
  ..  親ディレクトリ
  ~  ユーザのホームディレクトリ

 があります。

パイプリダイレクト

 パイプ、リダイレクトの説明の前に、標準入出力について説明しておきます。

 一般に、プログラムには、起動と同時に、標準入力stdin)、標準出力stdout)、標準エラーstderr)という、3つの入出力先が割り当てられます

 通常は、標準入力がキーボード、標準出力標準エラーが表示画面に結びつけられますが、これを別なものに切り替えるのがパイプリダイレクトです。

 ○ 基本的なパイプ、リダイレクト
  上の3つ(不等号のしるし)がリダイレクト、一番下(縦棒)がパイプです。

cmd < file標準入力をファイルへ切り替え
file から入力を読み込む)
cmd > file標準出力を file に出力
(既存ファイルがあれば上書き)
cmd >> file標準出力を file に出力
(既存ファイルがあれば、後半に追加)
cmd1 | cmd2 cmd1 の標準出力を cmd2 の標準入力とする

 ○ ちょっと難しいパイプ、リダイレクト
  使用するシェルによって、書き方が微妙に違います。以下は、tcsh の例。

cmd >& file標準出力と標準エラーを file に出力
(既存ファイルがあれば上書き)
cmd >>& file標準出力と標準エラーを file に出力
(既存ファイルがあれば、後半に追加)
(cmd > file1) >& file2 標準出力を file1 に、
標準エラーを file2 に出力(^^;
cmd1 |& cmd2cmd1 の標準出力と標準エラーを
cmd2 の標準入力とする

 なお、両側をパイプで結んで使うコマンドを、フィルタと呼ぶことがあります。

 ○ 有名なフィルタコマンド(の改悪版…(^^;;
 《 ファイル中の単語の出現頻度を調べる 》
$ cat /etc/motd | tr 'A-Z' 'a-z' | tr -cs 'a-z' '\012' | sort | uniq -c | sort -nr[Enter]
   9 the
   7 freebsd
   6 to
   5 and
   4 you
   4 with
   4 org
   4 if
   4 are
   3 www
   3 please
~~~~~~~~~~~~
$  

ジョブプロセスの管理

 FreeBSD は、複数のプログラム(正確にはプロセス)を同時に実行できる、マルチタスクの OS なので、コマンドラインからも複数のプロセスを扱えるようになっています

 ジョブプロセスは、どちらも似たような言葉ですが、一応、使い分けがされています。

プロセス:メモリ上に読み込まれた、プログラムの実行単位1個1個のこと
ジョブ:連携して動いているプロセスをひとまとまりにしたもの。
 上で紹介した「ファイル中の単語の出現頻度を調べる」コマンドは、全体で1つのジョブとなります

psプロセスの一覧を表示
jobsジョブの一覧を表示
killプロセス/ジョブにシグナルを送る
killall同上
fg %jobjobフォアグランドに回して実行
bg %jobjobバックグラウンドに回して実行
cmd &プログラムをバックグラウンドで実行
[Ctrl]+[Z]フォアグラウンドのジョブを停止
stop %job バックグラウンドで実行中の job を停止

 ジョブ管理の例1(終わるまで長い時間がかかるプログラムを「裏」に回して、その間にほかの仕事を片付ける)
 《 時間のかかるコマンドを実行 》
$ sleep 60[Enter]
[Ctrl][Z] 《 コマンドの実行を一時中断 》
^Z
Suspended
$   ←《 次のコマンドが受け付け可能になる 》
 ~~~
 《 ジョブの一覧を表示 》
$ jobs[Enter]
[1]  + Suspended                     sleep 60
 《 バックグラウンドで実行を再開 》
$ bg %1[Enter]
[1]    sleep 60 &
$  
 ~~~
 《 ほかの仕事とを進める 》
 ~~~
 《 終わった頃に[Enter]を押すと… 》
$ [Enter]
[1]    Done
$  
 もっとも、最初から「sleep 60 &」と、時間のかかるプログラムをバックグラウンドで起動させておけば、[Ctrl]+[Z] や「bg %1」の手間は掛からなかったワケですが、実行してから初めて気付くことも、よくあるので…(^^;;

 ジョブ管理の例2(root と 一般ユーザを行き来する)
 《 root になる 》
$ /usr/bin/su[Enter]
Password:《 root のパスワードを入力 》[Enter]
 《 root の仕事をする 》
# tail /var/log/security[Enter]
 ~~~
 《 root のシェルを停止させる 》
# suspend[Enter]

Suspended (signal)
 《 一般ユーザで作業 》
$ tail /var/log/messages[Enter]
 ~~~
 《 ジョブの一覧を表示 》
$ jobs[Enter]
[1]  + Suspended (signal)            /usr/bin/su
 《 再び root に戻る 》
$ fg[Enter]
/usr/bin/su
#  

● 続きは…

 …次回に続きます(多分(^^;

| | コメント (2) | トラックバック (0)

« 2009年8月 | トップページ | 2009年11月 »