« 2009年7月 | トップページ | 2009年9月 »

sshd を活用する

 SSH とは、Secure SHell の略で、もともとは、信頼できないネットワークを使って、離れた場所にある PC に安全にログインできるよう、通信データを暗号化するしくみのことですが、現在では、ログインだけに限らず、いろいろなプログラムがこの暗号化機能を活用しています。

 ちなみに、SSH と書いた場合は、通信路の暗号化を行なうしくみのことを、ssh と書いた場合には、SSH を実現するプログラムのことを指します。

 SSH に関連するプログラムとして、FreeBSD には、

sshd: SSH を使ったログインを受け付ける、ssh サーバ
ssh: 他の PC へ、SSH を使ってログインするために使う ssh クライアント
scp: SSH を使って、2台の PC 間で、安全にファイルをコピーするプログラム
sftp: SSH を使って、安全なファイル転送を行う ftp もどき

 などが準備されています。


■ SSH による通信のしくみ

 要は、データを送信側で暗号化して、受信側で復号化しているだけですが、実際に暗号化通信が始まるまでに、いろいろなワザが使われているので、簡単にさわりだけ、触れておきます。

● telnet による通信が始まるまで

 まず、ssh が登場する前に使われていた、telnet の場合から。

(1) クライアントサーバ間で TCP接続を確立

(2) パスワードにより、ユーザを認証
 1) クライアントからサーバに、ユーザ名とパスワードを送る
 2) サーバで、ユーザ名とパスワードを確認し、組み合わせが正しければ、ログインを許可

 通信データは暗号化されていないので、パスワードも生のままネットワークを流れます(^^;;;
 …ま、よく言えばシンプル、現在の基準でいえば無防備すぎですね。

● SSH (SSH-2) による通信が始まるまで

 続いて、最新のセキュリティ機能を満載した、ssh の場合です。

(1) クライアント~サーバ間で、TCP接続を確立

(2) 暗号の「」を交換し、暗号化された通信路を確立
 交換とはいっても、Diffie-Hellman法 という手法を使って、サーバとクライアントが、お互いに「ヒント」を出し合った後、両者それぞれが、自力で「」を作っているので、「」自体がネットワーク上を流れることはありません。

 この「」は、安全のため、1時間おきに変更されます。

 また、このときに、サーバの公開鍵を使って、サーバが本物かどうかの確認もしているらしいです。

(3) ユーザを認証

 大まかにいって、次の3種類のうちのどれかを使って、ユーザ認証が行なわれます。

 (A) 公開鍵認証方式
  1) [C] クライアントからサーバへ、ユーザ名を送信
  2) [S] サーバ側で、ランダムなデータを作成
  3) [S] 2) のデータをユーザの公開鍵で暗号化し、クライアントに送信
  4) [C] 送られたデータをユーザの秘密鍵で復号化し、ハッシュ値を計算
  5) [C] ハッシュ値をサーバに返送
  6) [S] 2) から求めたハッシュ値と、返送された値が一致すれば、ログインを許可
  ※ ちなみに、パスフレーズは、「秘密鍵」を復号するときに使われる「鍵」なので、ネットワークには流れません。

 (B) チャレンジ・レスポンス認証方式(あるいは、キーボード・インタラクティブ認証とも)
  1) [C] クライアントからサーバへ、ユーザ名を送信
  2) [S] サーバ側で、ランダムなデータを作成
  3) [S] 2) のデータ(チャレンジ)を、クライアントに送信
  4) [C] 送られたデータを、ユーザのパスワードを使って暗号化
  5) [C] 暗号化したデータ(レスポンス)をサーバに返送
  6) [S] 2) をユーザのパスワードで暗号化したものと、返送されたデータが一致すれば、ログインを許可

 (C) パスワード認証方式
  1) [C] ユーザ名とパスワードをサーバに送信
  2) [S] ユーザ名とパスワードの組み合わせが正しければ、ログインを許可

 公開鍵認証チャレンジ・レスポンス認証 では、ユーザのパスワード(または、公開鍵/秘密鍵)がネットワークを流れないのに、相手が正しいパスワードを持っていることを確認しています。 このしくみを考えた人は、すごいですね~(^-^)


■ 事前準備

● FreeBSD 側の準備

/etc/hosts に、ssh クライアントを動かす PC の IPアドレスと、ホスト名を書き込んでおきます。
(sshd が、接続してきたクライアントがニセモノでないか、DNS を使って確認しようとするため。)

 もちろん、自分のネットワークを管理している DNS サーバに登録してしまっても OK です(^^)

 /etc/hosts の内容:
::1                     localhost localhost.home.made
127.0.0.1               localhost localhost.home.made
192.168.1.2             thyme.home.made thyme
192.168.1.2             thyme.home.made.
192.168.1.100           host0 host0.home.made ← 追加
192.168.1.101           host1 host1.home.made ← 追加
192.168.1.102           host2 host2.home.made ← 追加
192.168.1.103           host3 host3.home.made ← 追加
 当然ですが、IPアドレスとホスト名は、ご自分が使っているものに書き換えて、使ってください(^^;;

○ 最初の ssh ログインを、信頼できないネットワーク経由で行なう必要がある場合は、ホスト鍵(FreeBSD の公開鍵)の指紋を控えておきます。 (「-l」の代わりに「-lv」を使うと、「random art」テクノロジーを満喫できます…(^^;
 《 RSA 公開鍵の指紋を確認 》
$ ssh-keygen -l -f /etc/ssh/ssh_host_rsa_key[Enter]
2048 46:77:1f:b3:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx /etc/ssh/ssh_host_rsa_key.pub (RSA)
 《 DSA 公開鍵の指紋を確認 》
$ ssh-keygen -l -f /etc/ssh/ssh_host_dsa_key[Enter]
1024 35:87:e0:bc:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx /etc/ssh/ssh_host_dsa_key.pub (DSA)
$  
 DSA は、RSA とは異なる非対称鍵暗号で、離散対数問題の難しさをもとに作られた暗号の方式です。
(ちなみに、上の方で出てきた Diffie-Hellman法も、離散対数問題の難しさが、「鍵」を守るカギになってます(^^;

● Windows 側の準備

 Windows から SSH を使って FreeBSD にログインする場合、Windows 上で動く ssh クライアントが必要になります。

 代表的なプログラム(…って、私が使ってるものだけど(^^;)を紹介します。

 これ以外のプログラムを使っても構いませんが、その場合には、SSH-2 に対応していることを確認しておきましょう。

 ○ Tera Term:日本人が開発している、SSH-2 対応のターミナルエミュレータ
  こちらにあるのが最新版で、チャレンジ・レスポンス認証に対応しています(旧称:UTF-8 対応 TeraTerm Pro)

  ◆ SourceForge.JP Tera Term プロジェクトトップページ
   http://sourceforge.jp/projects/ttssh2/

 ○ WinSCPsftpscp を使って、sshd が動いている PC との間でファイルのやりとりを行う

  ◆ WinSCP
    http://winscp.net/

 コマンドライン版sftpscp が好きな方(^^;は、こちら(↓)をどうぞ。

 ○ PuTTY:SSH-1/2 対応のターミナルエミュレータ

  ◆ PuTTY
    http://www.chiark.greenend.org.uk/~sgtatham/putty/

   ダウンロードページから、psftp.exepscp.exe がダウンロードできます。


■ 必要なソフトのインストール

 FreeBSD には、SSH 関連のソフトが初めから入っているので、普通は、新たにインストールする必要はありません。

 Windows 用のソフトのうち、Tera TermWinSCP については、Windows の流儀に従って、適当にインストールして下さい(^^;

 需要は少ないと思いますが(^-^;pscp.exepsftp.exe については、パスの通っているフォルダ(例えば C:\WINDOWS など)にコピーするのがお手軽でしょう。


■ sshd と、関連するプログラムの設定

 sshd は、ネットワーク経由で FreeBSD を使うときのセキュリティの要(かなめ)なので、sshd の設定に合わせて、ネットワーク関係のセキュリティ設定、具体的にはパケットフィルタTCP Wrapper の設定もここで済ましておくのがよいでしょう。

● sshd_config の設定

 以前は、sshd の設定ファイル /etc/ssh/sshd_config に「PasswordAuthentication yes」という1行を追加しないと、実質的に SSH を使ったログインはできなかったのですが、Tera Term がチャレンジ・レスポンス認証に対応してくれたお陰で、何も変更することなしに、SSH を使うことができるようになりました(^^)

● TCP Wrapper の設定

 TCP Wrapper とは、プログラム毎に、接続先に応じて、通信の許可/不許可を指定することができる、セキュリティ機能の1種です。

 …まあ、最近は、あまり活用されてないような気もしますが、一応、参考ということで…

 お約束として(^^;、sshd で TCP Wrapper が使えることを確認。
 《 sshd のありかを調べる 》
$ which sshd[Enter]
/usr/sbin/sshd
 《 sshd が使っているライブラリを表示 》
$ lld /usr/sbin/sshd[Enter]
/usr/sbin/sshd:
        libssh.so.4 => /usr/lib/libssh.so.4 (0x280b0000)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        libwrap.so.5 => /usr/lib/libwrap.so.5 (0x2810d000) ← これ
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        libroken.so.9 => /usr/lib/libroken.so.9 (0x2842c000)
$  
 次のような内容で、/etc/hosts.allow を作成します。FreeBSD に初めから入っている /etc/hosts.allowリネームして、1から書き直した方が多分早いです(^^)

 /etc/hosts.allow の内容:
#       /etc/hosts.allow

        ALL : localhost 127.0.0.1 : allow
#       ftpd : .home.made 192.168.1. : allow
        sshd : .home.made 192.168.1. : allow
        ALL : ALL : deny
 これも、「first win」=「早い者勝ち」ルールになっているので、条件にマッチした時点で、許可/禁止が決定します。

03行目:  ALL : localhost 127.0.0.1 : allow
 全てのプログラム(ALL)について、ローカルホスト(localhost127.0.0.1)からの接続は許可(allow)します。

05行目:  sshd : .home.made 192.168.1. : allow
 sshd については、LAN 内の PC (*.home.made192.168.1.*)からの接続を許可します。
 (LAN のドメイン名(.home.made)とネットワークアドレス(192.168.1.)については、お使いのものに合わせてくださいね(^^)。)

06行目:  ALL : ALL : deny
 全てのプログラムについて、あらゆる接続(ALL)を禁止(deny)します。

● パケットフィルタの設定

 「パケットフィルタ (ipfw) の設定」を参照してください(^^)

  ◆ パケットフィルタ (ipfw) の設定
   http://murasaki.cocolog-nifty.com/cloud/2009/08/ipfw-a0b2.html

● 公開鍵認証について

 今回は使いませんが、信頼できないネットワーク経由で SSH を使いたい場合、あるいは、信頼できないネットワークからの SSH ログインを許可しなくてはならない場合には、公開鍵認証だけを許可し、その他の認証によるログインを禁止すれば、より安全に FreeBSD を運用することができます。

(私のいい加減な計算(^^;によれば、8文字のパスワードのパターンは7.2×10^16通りしかありませんが、1024ビットの公開鍵のパターンは、10^150通り以上あります。)


■ sshd を使ってみる

 ここでは、sshd を、 FreeBSD の起動と同時に使えるようにする方法と、Windows 用のソフトの代表として、Tera Termsftppsftp.exe)の使い方を簡単に説明します。

psftp.exe は代表じゃないでしょ… という苦情は受け付けません(^^;;

● sshd の起動

 FreeBSD のシステム設定ファイル、/etc/rc.conf に次の1行を追加します。
sshd_enable="YES"
 その後、PC を再起動します。
# reboot[Enter]
 FreeBSD が起動したら、sshd が起動していることを確認します。
 ソケットの状態を表示 》
$ sockstat[Enter]
USER     COMMAND    PID   FD PROTO  LOCAL ADDRESS         FOREIGN ADDRESS
root     sshd       651   3  tcp4   192.168.1.2:22        *:*   ← これ
root     sshd       651   5  stream -> ??
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
$  
● Tera Term で FreeBSD にログイン

 では、Tera Term を使って、FreeBSD にログインしてみましょう。

 ちなみに、Tera Term最初に起動するときは、設定ファイルにあれこれと書き込むことになるので、コンピュータの管理者 として起動した方がいいです

(1) Tera Term を起動
 スタートメニューから辿る(たどる)なり、デスクトップのアイコンを使うなりして、Tera Term を起動します。
 「新しい接続」ウインドウが表示されたら、「ホスト」欄に、FreeBSD が動いている PC の IPアドレスを入力して「OK」ボタンを押します。

SSH で FreeBSD に接続

(2) ホスト鍵の確認
 初めて接続する場合には、「セキュリティ警告」ウインドウが開くので、表示された「サーバ側のホスト鍵指紋」が、FreeBSD のものと一致していることを確認して「続行」ボタンを押します。
 この画面では、「DSA鍵」が使われているので、FreeBSD の公開鍵のうち、「DSA」の方と比較します。
(この画面を撮り直すために、サーバ公開鍵を削除た後でログインし直すまで、てっきり、RSA公開鍵 を使っているものだと思い込んでました(^^ゞ。)

 「このホストを known hosts リストに追加する」にチェックマークを付けておくと、同じホストに接続する場合には、この画面は表示されません。
(もし、表示されたら、ニセモノの可能性が大です(^^;

サーバのホスト鍵指紋

(3) ログイン認証
 続いて、「SSH認証」画面が表示されるので、ログイン方法として「チャレンジレスポンス認証を使う」を選んで、ログインを行います。
 ・「チャレンジレスポンス認証を使う」にチェックマークを入れる
 ・「ユーザ名」に FreeBSD のユーザ名を入力
 ・「OK」ボタンを押す

チャレンジ・レスポンス認証

(4) パスワード入力
 ・「SSH認証チャレンジ」画面で、パスワードを入力
 ・「OK」ボタンを押す

パスワードを入力

 これで、FreeBSD にログインできるはずです。

● Tera Term の設定

 FreeBSD にログインできることが確認できたら、Tera Term の設定も済ましておきましよう。
日本語エンコードの設定
 ・「設定」→「端末(T)」
  ・「漢字-受信」:UTF-8 → EUC、「漢字-送信」:UTF-8 → EUC (FreeBSD の場合)

・フォントの設定
 ・「設定」→「フォント(F)」
  ・お好きなものを(^^)
   私は、MSゴシックの10ptを使ってます

・ログイン認証方式の選択
 ・「設定」→「SSH認証(A)」
  ・「チャレンジレスポンス認証を使う」にチェックマーク

 これらの設定が終わったら、忘れずに、

・「設定」→「設定の保存(S)」で、TERATERM.INI に変更を保存しておきます。

● Tera Term を終了する

 Tera Term を終了する場合は、
(1) 「exit」コマンドで、FreeBSD からログアウトする
(2) FreeBSD を「shutdown」させる
 のどちらかの操作をすれば、FreeBSD(sshd)との接続が切断されると同時に、Tera Term も終了します。


● sftp の使い方

 もう一つ、SSH を使ったプログラムの例として、sftp の使い方を紹介します。
 ワイルドカードが使えるのが、sftp の魅力ですね(^^)

【簡単な解説】
 以下では、次の操作を行っています。

○ Windows の D:\FBex フォルダの下に、log フォルダを作り、FreeBSD の ~/work/logディレクトリにある *.log ファイルをコピー
○ FreeBSD の ~/work ディレクトリの下に、mini ディレクトリを作り、Windows の D:\FBex\mini フォルダにある mini* ファイルをコピー

 sftp のコマンドで、最初に「!」が付いているのが Windows(ローカルホスト)に対する操作指示、付いていないのが sftp または FreeBSD(リモートホスト)に対する操作指示です。

【操作方法の例】

 まず、Windows の「コマンド プロンプト」を開きます。
 《 あらかじめ、目的のドライブ、フォルダに移動しておく 》
C:\Documents and Settings\melissa>d:[Enter]

D:\>cd FBex[Enter]

 《 sftp (psftp.exe) で、FreeBSD に接続 》
D:\FBex>psftp 192.168.1.2[Enter]
The server's host key is not cached in the registry. You
have no guarantiee that the server is the computer you
think it is.
The server's dss key fingerprint is: ← dss と言ってるけど、DSA のこと
ssh-dss 1024 35:87:e0:bc:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx:xx
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on conneting.
If you want to carry on conneting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n) y[Enter] ← FreeBSD の公開鍵を Windows 側に保存
login as: violet[Enter] ← ユーザ名を入力
Using keyboard-interactive authentication.
Password: パスワードを入力[Enter]
Remote working directory is /usr/home/violet
 《 FreeBSD側:work/log ディレクトリに移動 》
psftp> cd work/log[Enter]
Remote directory is now /usr/home/violet/work/log
 《 FreeBSD側:ディレクトリの中身を確認 》
psftp> ls[Enter]
Listing directory /usr/home/violet/work/log
drwxr-xr-x    2 violet   violet         512 Jun 28 10:20 .
drwxr-xr-x    4 violet   violet         512 Jun 27 15:52 ..
-rwxr-xr-x    1 violet   violet         278 Jun 27 15:43 fd.log
-rwxr-xr-x    1 violet   violet       17406 Jun 27 15:29 jvim3.log
-rwxr-xr-x    1 violet   violet         210 Jun 27 15:29 n.log
 《 Windows側:現在のフォルダを確認 》
psftp> ! cd[Enter]
D:\FBex
 《 Windows側:log フォルダを作成 》
psftp> ! mkdir log[Enter]
 《 Windows側:log フォルダへ移動 》
psftp> lcd log[Enter]
New local directory is D:\FBex\log
 《 バイナリ転送モードに設定 … って、psftp にはなかった(^^;; 》
psftp> binary[Enter]
psftp: unknown command "binary"
 《 「*.log」にマッチするファイルを転送(取得) 》
psftp> mget *.log[Enter]
remote:/usr/home/violet/work/log/fd.log => local:fd.log
remote:/usr/home/violet/work/log/jvim3.log => local:jvim3.log
remote:/usr/home/violet/work/log/n.log => local:n.log
 《 Windows側:フォルダの中身を確認 》
psftp> ! dir[Enter]
 ドライブ D のボリューム ラベルがありません。
 ボリューム シリアル番号は BCDF-1234 です

 D:\FBex\log のディレクトリ

2009/08/27  20:27    <DIR>          .
2009/08/27  20:27    <DIR>          ..
2009/08/27  20:29               278 fd.log
2009/08/27  20:29            17,406 jvim3.log
2009/08/27  20:29               210 n.log
               3 個のファイル              17,894 バイト
               2 個のディレクトリ   8,901,455,872 バイトの空き領域

 《 FreeBSD側:親ディレクトリに移動 》
psftp> cd ..[Enter]
Remote directory is now /usr/home/violet/work
 《 FreeBSD側:miniディレクトリを作成 》
psftp> mkdir mini[Enter]
mkdir /usr/home/violet/work/mini: OK
 《 FreeBSD側:miniディレクトリに移動 》
psftp> cd mini[Enter]
Remote directory is now /usr/home/violet/work/mini
 《 Windows側:..\mini フォルダへ移動 》
psftp> lcd ..\mini[Enter]
New local directory is D:\FBex\mini
 《 Windows側:フォルダの中身を確認 》
psftp> ! dir[Enter]
 ドライブ D のボリューム ラベルがありません。
 ボリューム シリアル番号は BCDF-1234 です

 D:\FBex\mini のディレクトリ

2009/08/26  20:17    <DIR>          .
2009/08/26  20:17    <DIR>          ..
2009/06/19  21:41             1,130 mini_httpd.c.diff
2009/06/19  21:41             2,320 mini_httpd.c.diff2
2009/06/19  21:41             2,502 mini_httpd.c.diff3
2009/06/19  21:41             1,447 mini_httpd.conf
               4 個のファイル               7,399 バイト
               2 個のディレクトリ   8,901,455,872 バイトの空き領域

 《 「mini*」にマッチするファイルを転送(送信) 》
psftp> mput mini*[Enter]
local:mini_httpd.c.diff => remote:/usr/home/violet/work/mini/mini_httpd.c.diff
local:mini_httpd.c.diff2 => remote:/usr/home/violet/work/mini/mini_httpd.c.diff2
local:mini_httpd.c.diff3 => remote:/usr/home/violet/work/mini/mini_httpd.c.diff3
local:mini_httpd.conf => remote:/usr/home/violet/work/mini/mini_httpd.conf
 《 FreeBSD側:ディレクトリの中身を確認 》
psftp> ls[Enter]
Listing directory /usr/home/violet/work/mini
drwxr-xr-x    2 violet   violet         512 Aug 27 20:36 .
drwxrwxrwt    8 violet   violet         512 Aug 27 20:32 ..
-rw-r--r--    1 violet   violet        1130 Aug 27 20:36 mini_httpd.c.diff
-rw-r--r--    1 violet   violet        2320 Aug 27 20:36 mini_httpd.c.diff2
-rw-r--r--    1 violet   violet        2502 Aug 27 20:36 mini_httpd.c.diff3
-rw-r--r--    1 violet   violet        1447 Aug 27 20:36 mini_httpd.conf
 《 FreeBSD(の sshd)から切断 》
psftp> bye[Enter]

 《 コマンドプロンプトを閉じる 》
D:\FBex>exit[Enter]
■ sshd が動いたら…

 sshd が問題なく動くことを確認したら、安全でないサーバプログラム(デーモン)を止めます
 各デーモンの停止方法は、デーモンを動かした人に聞いて下さい。 動かしたのが自分ならば、なんとかするように(^-^;

(FreeBSD の流儀に従っていれば、/etc/rc.conf の「telnetd_enable="YES"」などと書かれた行を探して「# telnetd_enable="YES"」とコメントアウトするか、/etc/inetd.conf の各行の最初に「#」を書いて、FreeBSD を再起動すれば、止まるはず…(^^;

 FreeBSD で、どんなサーバプログラム(デーモン)が動いているかは、前述の sockstat で確認できます。

● telnetd
 telnet 接続を受け付けるプログラム。
 telnet の通信データは暗号化されないので、動いているのを見つけたら、問答無用で停止させます。

(外部と直接つながっていない LAN環境であっても、無線LANを使っていて、その暗号化方式の選択を間違うと、数分で無線LANの暗号が解読されてしまう、という話もありますので、暗号化されない telnet のようなプログラムを使うのは危険だと、きっぱりあきらめた方がいいでしょう。)

● rlogind、rshd
 ssh が登場する以前に使われていた、通称 r コマンド と呼ばれるプログラムの接続を待ち受けるデーモン。
 やはり、通信データは暗号化されないので、動いているのを見つけたら、停止させます。

● ftpd
 Anonymous ftp 専用に仕立てているなら、一応、問題ありませんが、FreeBSD のユーザ名で ftpd に接続できるようなら、停止させてしまいましょう。
ftp のデータも暗号化されないので、ftpd にログインする際のパスワードを「のぞき見」される危険があります。)

 sshd が動いていれば、ftp の代わりに、暗号化された通信路上で安全にデータのやりとりができる WinSCPsftp が使えます。

● inetd
 外部からの接続要求があったとき、それに応じて適切なデーモンを起動する機能を持った、サーバプログラム。
 通称は、インターネット・スーパー・デーモン

 inetd 自体は、起動していても、とりたてて問題ありませんが、/etc/inetd.conf の中で、例えば telnetd が自動起動するように設定されていると、実質的に telnetd を常時起動しているのと同じことになってしまいます(^^;

 メモリが貴重だった昔はともかく、最近は、inetd を使わずに、単独で接続を待ち受けるデーモンも多いので、/etc/inetd.conf の中身を確認して、止めても問題なさそうなら、inetd 自体を止めてしまいましょう。

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

RSA暗号のお話

 今週は、お盆があったり、風邪を引いて寝込んだり、その退屈しのぎに本を買ってきたら、案外面白くてつい読み進めてしまったり… ということがあって筆が進まなかったので、番外編をお送りします(^-^;


● RSA 暗号とは

 RSA暗号とは、SSLSSH 等に使われている暗号の一方式で、非対称鍵暗号に分類されます。

 「RSA」という名前は、この暗号を発明した3人の名前の頭文字に由来しています。


● 非対称鍵暗号(公開鍵暗号)

 非対称鍵暗号方式の説明の前に、まず、分かりやすい共通鍵暗号(対称鍵暗号、秘密鍵暗号とも呼ばれます)方式について、簡単に説明しておきます。

 共通鍵暗号は、閉める(暗号化する)ときと開ける(復号化する)ときに、同じ鍵を使う方式の暗号です。

(「復号」は、正規の鍵を持っている人が暗号を解除するときに使われる言葉です。 意図しない第三者が暗号を解除する場合は「解読」と呼ばれます。)

 ドアの鍵に例えると、鍵穴に鍵を差し込んで、右に回せば施錠され、左に回せば解錠される、といった、昔からなじみのあるタイプの暗号の方式です。

 一方の、非対称鍵暗号は、2つ(1対)の鍵を使う暗号で、片方の鍵で閉めたら(暗号化したら)、もう一方の鍵でしか開ける(復号化する)ことができないという、面白い性質があります。

 先ほどのドアに例えると、鍵穴にAの鍵を差し込んで右に回して施錠したら、解錠はBの鍵を差し込んでさらに右に回さないといけない、といった感じの暗号です。


● 非対称鍵暗号のメリット

 非対称鍵暗号のいいところは、まず1つには、「おおっぴらに、秘密のやりとりができる」ところです(^^;

 まず、共通鍵暗号では、鍵を第三者に知られてしまうと、秘密が守れないので、鍵をどうやって意中の人に渡すか、というのが頭を悩ます問題になります。
(鍵が『悪意を持った第三者』の手に渡ってしまったら、密かに暗号を「解読」するのも、ニセの暗号文を送りつけるのも、自由自在ですよね…)

 一方、非対称鍵暗号では、2つある鍵の片方を公開用の鍵、残りを自分だけの秘密の鍵にして、公開用の鍵を必要な人たちに文字通りばらまいてしまいます。
 すると、誰でも公開鍵を使って暗号を作ることができるけど、それを復号できるのは、秘密鍵を持っている自分だけ、という、非常に好ましい状況を作ることができます。

 この「暗号の鍵を公開してしまう」というインパクトがあまりに強かったため、共通鍵暗号は公開鍵暗号とも呼ばれます。


 それと、もう一つ、非対称鍵暗号の(正しくは、RSA暗号の)いいところは、間違いなく自分が送りました、という証明(専門的には「署名」といいます)ができることです。

 文書に署名をして送りたい場合、Aさんは自分の秘密鍵 SKa で施錠(暗号化)したものを、相手の公開鍵 PKbさらに施錠(暗号化)して、Bさんに送ります。
 Bさんは受け取った暗号を、自分の秘密鍵 SKb で解錠(復号)したあと(ここまではいつも通り)、さらにAさんの公開鍵 PKa で解錠(復号)して初めて、本文を読むことができます。

 ここで、非対称鍵暗号では、片方の鍵で施錠(暗号化)したら、残りの鍵でしか解錠(復号)できないということを思い出すと、Aさんの公開鍵 PKa で解錠できる暗号を作れるのは、対になっている秘密鍵 SKa を持っているAさんだけ、つまり、文書の送り主は間違いなくAさんだ、ということが証明できるわけです。


● RSA暗号 破れる!?

 …なにか、扇情的な見出しですが(^^;;、現在の暗号に対する考え方の基礎になってる話なので、紹介しておきますね。


 RSA暗号には、実は、よく知られた弱点があります。
 それは、秘密鍵を、公開鍵から数学的に導き出せる、というものです。

 以下、ごく簡単に、RSA暗号の公開鍵の正体と、秘密鍵の求め方を説明すると…

 RSA暗号の公開鍵の正体は、2つの数字を掛け合わせて作られた数字です。
 そして、公開鍵を2つの数字に分解し、それをある公式に入れれば、秘密鍵が求まってしまいます。


 では、なぜ、公開鍵から秘密鍵がばれてしまうという、暗号としては致命的とも思われる欠点を持つ、RSA暗号が使われているかというと…

 まず、現在では、暗号の研究と、「計算機」の高性能化が非常に進んでいて、素人考えの暗号では、すでに秘密を守れない、ということがあります。

 もう一つは(こちらが本命ですが(^^;)、大きな数の素因数分解が、非常に時間が掛かる作業である、ということが挙げられます。


 現在、RSA暗号で一般に用いられている公開鍵は、1024ビット(十進数に直すと、300桁を超える数字になります)という、途方もなく大きな数になっています。
 ちなみに、この宇宙に存在する「原子」の総数が 10^80 個(十進数で80桁)程度といわれているので、その途方のなさが分かると思います…(^^;;;

 これを、正攻法で、素数で順に割っていって答えを探そうとすると、宇宙の寿命が尽きても、計算し尽くせません
(というか、全宇宙の「原子」の総数を超えてしまうため、そもそも、素数の一覧表を書き留めることすらできません(^^;


 …ということで、もっと別の素因数分解方法が研究され、2005年には、2万ドルの懸賞が掛けられていた、640ビット(十進数で193桁)のRSA公開鍵が計算により破られています。

 ◆ MathWorld Headline News: RSA-640 Factored (英語、注意(^-^;
  http://mathworld.wolfram.com/news/2005-11-08/rsa-640/

 超~要約すると(^^;

 一般数体ふるい法(GNFS) を用いて、2.2GHz の CPU 80台を使い、3ヶ月かけてデータを集め、そのあと 1.5ヶ月かけて連立方程式を解きました

 …だそうです。

 意外と簡単に解けてしまったんだな~というのが私の感想ですが、とりあえず、現在主流の1024ビットRSA公開鍵を素因数分解するには、640ビットRSA公開鍵のときの約1000倍の時間が必要になりますし、2048ビットRSA公開鍵を使えば、さらにその10万倍の時間が必要になります。

 そのほかにも、「一般数体ふるい法」自体の弱点として、この方法は、大量のデータ処理を伴うので、用意できるメモリとHDDの容量で、素因数分解できる数字の最大値が制限されてしまうそうです。


 …ということで、RSA暗号も(決して油断はできませんが)、すぐに使い物にならなくなる状況では、ないようです。


● 暗号との新しいつきあい方

 前述のように、暗号の「破られやすさ」が、数値的に評価できるようになったことで、暗号を使う側にも、「秘密は、永遠に守りきれるものではない。ただ、必要な間だけ、暗号が破られなければいい」といった、新しい考え方が生じています。


 例えば、クレジットカードの情報なら、100年間秘密が守れれば、まず問題はないだろうし、極端な話、オークションの入札金額の連絡なら、オークションが終わるまでの数日~数時間の間だけ秘密が守れれば十分、という考え方です。


 そして、暗号を破ろうとする「たくらみ」に対しては、暗号の鍵を短い時間で次々と替えて、鍵が解析され破られる頃には、その鍵はもう使ってないよ~、という運用をすることで対抗しようとしています。


 …そういうわけで、会社や学校で、パスワードは定期的に変えなさい、というお達しが出ていたら、最近の暗号化技術に対して、正しい認識を持った人がいるんだな~と思って、(めんどくさいけど(^^;)協力してあげましょう。

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

パケットフィルタ (ipfw) の設定

 現在、ネットワークの主流は TCP/IP ということで異論はないと思いますが(^^;;、この TCP/IP 上を流れるデータ(パケット)のうち、必要なものだけを通し、不要なものを通さない、パケット選り分け(よりわけ)の役目を果たすのが、パケットフィルタです。

 一般には、パケットフィルタよりも、ファイアウォールという名前の方が、通りがいいようですが…。


 …それと、毎度のことながら、説明が長いので、注意してください(^^;;;


■ ipfw とは

 FreeBSD のパケットフィルタは、パケットの選り分けという基本的な機能のほかに、NAT帯域制御なども備える、高機能なものです。
 そして、このパケットフィルタを設定するプログラムとして、ipfw があります。

 一般に、パケットフィルタは、パケットの種類と IPアドレス、ポート番号の組み合わせにより、パケットを通す/通さないを決めますが、パケットフィルタ=ファイアウォールと普通に思われているように、外部からの不正アクセスを防止するのに、とても効果的です。

 しかし、パケットフィルタも決して万全ではないので、ほかのセキュリティがおろそかにならないよう、注意しましょう。


■ 事前準備

 本来なら、ネットワーク(特に、TCP/IP)の仕組みや、インターネット上で流行っているウイルスの振る舞いなどを勉強してから、パケットフィルタの構築に入るのがよいのですが、今回は、とりあえず「パケットフィルタを動かすこと」を目標にしてみます。

 基本的な注意ですが、パケットフィルタを設定するときは、必ず、コンソールからログインして行いましょう。
 ネットワーク経由でログインして作業をしていると、パケットフィルタの設定を間違った瞬間に、FreeBSD から閉め出されてしまいます(^^;


■ ipfw のインストール

 ipfw は、最初から FreeBSD の中に含まれているので、改めてインストールする必要はありません。

 ただし、パケットフィルタの機能は、カーネルモジュールという形で分離されているので、パケットフィルタを使えるようにするために、ちょっとしたワザが必要になります(後述)。


■ ipfw の設定

 FreeBSD には、/etc/rc.firewall という、パケットフィルタのサンプルが準備されていますが、今回は、まったくのオリジナルで、比較的単純、かつ、そこそこ役に立つパケットフィルタ(私が使っているもの(^^;;)を作ってみます。

 では、/etc/rc.fw の名前で、以下の内容のファイルを準備しましょう。
#!/bin/sh
#       /etc/rc.fw

  fw_cmd="/sbin/ipfw -q"
  fw_add="${fw_cmd} add"
  my_ifn="re0"
  my_net="192.168.1.0/24"

# flush old rules
  ${fw_cmd} -f flush

# rules on localhost
  ${fw_add} 100 allow     all  from any to any  via lo0
  ${fw_add} 200 deny      all  from any to 127.0.0.0/8
  ${fw_add} 300 deny      all  from 127.0.0.0/8 to any

# accelerator
  ${fw_add}     allow     tcp  from any to any  established
  ${fw_add}     allow     all  from any to any  frag
  ${fw_add}     check-state

# deny rules
  ${fw_add}     deny      tcp  from any 137-139,445 to any
  ${fw_add}     deny      tcp  from any to any 137-139,445
  ${fw_add}     deny      udp  from any 137-139,445 to any
  ${fw_add}     deny      udp  from any to any 137-139,445

# my network
  ${fw_add}     allow     udp  from ${my_net} to me 53   keep-state
  ${fw_add}     allow     udp  from ${my_net} to me 123  keep-state
  ${fw_add}     allow     tcp  from ${my_net} to me  setup
  ${fw_add}     allow     all  from ${my_net} to me
  ${fw_add}     allow     all  from me to ${my_net}

# outer network
  ${fw_add}     allow     udp  from ${my_net} to any 53   keep-state
  ${fw_add}     allow     udp  from ${my_net} to any 123  keep-state
  ${fw_add}     allow     tcp  from ${my_net} to any  setup

# icmp from/to outer network
  ${fw_add}     allow     icmp from any to any  in \
                               icmptypes 0,3,4,11,12
  ${fw_add}     allow     icmp from any to any  out \
                               icmptypes 3,4,8,11,12

# defalut to deny (with log)
  ${fw_add}     deny  log all  from any to any
● FreeBSD のパケットフィルタの基本

 まず最初に、FreeBSD のパケットフィルタの動作を簡単に説明しておくと…

 パケットフィルタは、「ipfw add」コマンドで、ルールを1つずつ追加して作ります。
 ルールは、「番号」を指定しないと、今ある一番大きいルールの番号+100 という「番号」が自動的に振られます。

 また、FreeBSD のパケットフィルタには、「first win」=「早い者勝ち」という原則があり、
  (1) 1つ1つのパケットに対して、「番号」の小さいルールから順番に比較を行う
  (2) パケットが、ルールの「条件」とマッチ(一致)したら、
   (2.1) それが「許可allow)」のルールならば、そのパケットを通過させて終了
   (2.2) それが「禁止deny)」のルールならば、そのパケットを廃棄して終了
  (3) マッチしなかったら、次の「番号」のルールに進む
 という処理を行っています。

 この、「早い者勝ち」という原則があるため、FreeBSD のパケットフィルタは、最初は範囲が限定されたルールから始めて、だんだんと範囲を広げていくようにすると、分かりやすいルールを書くことができます(^^)

 なお、パケットフィルタを使う人のポリシーの違いによって、上の例で「許可」しているパケットが、ほかでは「禁止」すべし!と言われている場合もあります。
 でも、どちらかが正しくて、もう一方が誤りとは決め付けられない場合もあるので、使いながら手直ししてみて下さい(^^;;


● ファイル内容の解説

01行目:#!/bin/sh
 このスクリプトを実行するプログラムを指定します
 ここでは、「/bin/sh」を指定しています。

04~07行目:
 sh のシェル変数を設定しています。
 シェル変数に設定した内容は、あとで「${シェル変数}」の形で呼び出すことができるので、ここでは、主に、キーボードを打つ回数を節約する目的で(^^;;、活用しています

04行目:fw_cmd="/sbin/ipfw -q"
 パケットフィルタを設定するためのコマンドを、シェル変数に設定します。
 「-q」は、ipfw を無口にするためのオプションです

05行目:fw_add="${fw_cmd} add"
 パケットフィルタのルール追加用に使うコマンドです。
 「${fw_cmd}」は「/sbin/ipfw -q」に展開されるので、結局、これは「/sbin/ipfw -q add」を設定したのと同じ効果があります

06行目:my_ifn="re0"
 FreeBSD のネットワークインターフェイスの名前を設定します。
 ただし、今回は(設定するルールが単純なので)使わずに済んでます(^^;

07行目:my_net="192.168.1.0/24"
 わが家の LAN の、ネットワークアドレスです。
 必ず、ご自分が使っているアドレスに書き換えて使って下さい(^^;;

10行目:${fw_cmd} -f flush
 ここから、パケットフィルタの設定が始まります。
 パケットフィルタに新しいルールを設定する前準備として、いまあるルールをすべて破棄します。

13~15行目:
 ローカルホスト関連の設定
 この3行は、決まり文句みたいなものなので、このまま覚えてしまいましょう(^^)
 ちなみに、この3行にだけ、ルール番号(100番~300番)が指定してあります

13行目:${fw_add} 100 allow all from any to any via lo0
 ループバックインターフェイスを通る(via lo0)パケットは、発信元・送信先に関わらず(from any to any)、全ての種類のパケット(all)を許可(allow)します。
 (ループバックインターフェイスには、PC 外部からの(PC 外部へも)パケットは流れないので、全てのパケットを信用します

14行目:${fw_add} 200 deny all from any to 127.0.0.0/8
 「送信先が自分自身(to 127.0.0.0/8)」を名乗るパケットがあれば、それは禁止(deny)します。

 パケットフィルタの原則が「早い者勝ち」であることを考えると、「すぐ上のルールにマッチしなかった」このパケットは、「外部から来たか、外部に出て行こうとしてる」パケットのはずで、このような「オレオレ詐欺パケット」は、捨ててしまうに限ります

15行目:${fw_add} 300 deny all from 127.0.0.0/8 to any
 「発信元が自分自身(from 127.0.0.0/8)」を名乗る「オレオレ詐欺パケット」も、上と同じ理由で捨てます

18~20行目:
 アクセラレータ の設定。
 パケットフィルタのルールは、「番号」の若い順から比較されるので、パケットの遅延とシステム負荷を減らす観点から、過去に「許可」の判定が出ているパケットは、早めに許可しておくのが得策です

18行目:${fw_add} allow tcp from any to any established
 TCP パケットのうち、すでに接続が確立している(established)ものを許可します

19行目:${fw_add} allow all from any to any frag
 大きすぎて、複数のパケットに分割された(frag)パケットを許可します

20行目:${fw_add} check-state
 動的ルールで許可された、同じ相手先(パケットの種類と IPアドレス、ポート番号が全て一致したときに限ります)との送受信を許可します。
 (詳細は、keep-state のところで(^^)

23~26行目:
 (ローカルホストを除く)全体的な禁止ルールの設定。
 ここでは、Windows が使う NetBIOS137,138/TCP,UDP)と ファイル共有139/TCP,UDP および 445/TCP,UDP)を禁止しています

23行目:${fw_add} deny tcp from any 137-139,445 to any
24行目:${fw_add} deny tcp from any to any 137-139,445
25行目:${fw_add} deny udp from any 137-139,445 to any
26行目:${fw_add} deny udp from any to any 137-139,445

29~33行目:
 LAN 内部を流れるパケットに関する設定です

29行目:${fw_add} allow udp from ${my_net} to me 53 keep-state
 FreeBSD 上で動いている、DNS サーバunbound)への接続を許可する設定。
 LAN 内部から(from ${my_net}) FreeBSD の 53番ポートへの(to me 53UDP 接続を受け付け、動的ルールに追加(keep-state)します。

 発信元と送信先が「合意」したあとで本番の通信が始まる TCP とは異なり、UDP は、送信元が受信先へパケットを一方的に送りつけて終わり、という通信方式ですが、もし、通信相手の IPアドレスとポート番号を記憶しておくことができれば、その相手だけを選んで、パケットのやりとりを許可することができます。

 この、通信相手の IPアドレスとポート番号、そしてパケットの種類を(ある意味、PC の搭載メモリ量と CPU パワーにものを言わせて、力まかせで(^^;;)記憶して、一定時間だけ通信を許可するしくみを、動的ルールと呼びます

30行目:${fw_add} allow udp from ${my_net} to me 123 keep-state
 FreeBSD 上で動いている、NTP サーバntpd)への接続を許可する設定。
 LAN 内部からの時刻(NTP)問い合わせを受け付け(udpto me 123)、動的ルールに追加(keep-state)します

31行目:${fw_add} allow tcp from ${my_net} to me setup
 LAN 内部から FreeBSD への、TCP 接続開始要求setup)を受け付けます。
 TCP の接続が確立したあとは、その接続が切断されるまで、前述の established のルールにより、発信元と接続先 (FreeBSD) 間の通信が許可されます

32行目:${fw_add} allow all from ${my_net} to me
 LAN 内の PC から FreeBSD に向けて発信されたパケットを全て許可します

33行目:${fw_add} allow all from me to ${my_net}
 FreeBSD から LAN 内部の PC に向けて発信するパケットを全て許可します(※)

※ ただし、FreeBSD で、外部向けのサービスを提供している場合(インターネット向けのWebサーバを立てている場合など)には、FreeBSD から LAN 内部に向けて発信するパケットは、「許可」ではなく「禁止」にしておいた方がよいかもしれません。
(万一、Webサーバのバグなどが原因で FreeBSD が乗っ取られてしまった場合、ここを拠点に、LAN 内部の PC に対して攻撃が行なわれる可能性があるので…)

 …ところで、気付いている方もいると思いますが、単に必要なパケットを通すのだけが目的なら、32行目と33行目があれば、29~30行目のルールはなくても、結果は変わりません(^^;;

 でも、このように、普段よく使われるルールを分けておくと、32行目や33行目にマッチしたパケットがあったときに、あれ、これはなんだろう、と異変に気付くきっかけになるので、このように一見無駄な設定をしています。

36~38行目:
 ローカルホストおよび LAN 以外… つまり、インターネットに関する設定。

 ここでの考え方として、TCP、UDP については、LAN 内部から発信されるパケットのみを許可します。
 インターネットから入ってくるパケットは(LAN 内部から発信されたパケットに対する応答を除き)、47行目より前のルールの中でマッチするものがないので、結局、47行目の「すべて禁止」ルールにより全て破棄されます

36行目:${fw_add} allow udp from ${my_net} to any 53 keep-state
 LAN 内の PC(ここでは、LAN 内の PC に、FreeBSD も含まれていることに注意(^-^;)が発信元となっている DNS 問い合わせを許可し、動的ルールに追加します。
 (動的ルールに合致したパケットは、前述の check-state ルールにより許可されます)

37行目:${fw_add} allow udp from ${my_net} to any 123 keep-state
 LAN 内の PC が発信元となっている、時刻(NTP)問い合わせを許可し、動的ルールに追加します

38行目:${fw_add} allow tcp from ${my_net} to any setup
 LAN 内の PC が発信元の、TCP 接続要求を許可します。
 (接続が確立した後の通信は、established ルールにより許可されます)

41~44行目:
 ICMP に関する設定。
 ただし、LAN 内部向けについては、32,33行目で、すでに全種類のパケットについて許可済みなので、ここでの設定は、インターネット用の設定ということになります。
 (このあたりが、パケットフィルタは難しい、と思われる原因なんでしょうね。 …慣れてしまえば、なんとかなるものですが(^^;

41行目:${fw_add} allow icmp from any to any in \
42行目:                icmptypes 0,3,4,11,12
 インターネットからやってくる(inICMP パケットのうち、icmptypes で指定したものを許可します

43行目:${fw_add} allow icmp from any to any out \
44行目:                icmptypes 3,4,8,11,12
 インターネットへ出て行く(outICMP パケットのうち、icmptypes で指定したものを許可します

 ここで、icmptypes の後ろの数字は、それぞれ
   0番:エコー応答(Echo Reply) … ping に対する応答
   3番:宛先へ到達不可(Destination Unreachable
   4番:通信速度の抑制要求(Source Quench
   8番:エコー要求(Echo Request) … ping による応答要求
  11番:パケットの寿命が尽きた(Time Exceeded
  12番:パケットのパラメータ異常(Parameter Problem
 に対応する ICMP のパケットを指します。

 ちなみに、41行目と43行目の最後の「 \ 」(FreeBSD 上では「 」に見えます)は、/bin/sh のコマンドを1行で書ききれなかったときに、次の行に続くということを表す「決まりごと」です(^^)

47行目:${fw_add} deny log all from any to any
 あらゆるパケット(all from any to any)を廃棄します。
 また、それらのパケットについての情報を、ログ(log)に残します(ファイル名は、/var/log/security です)。

● ファイルの確認

 パケットフィルタは、セキュリティ上、とても重要な設定なので、作成した /etc/rc.fw および関連するファイルが、適切なパーミッションを持っていることを確認しておきます。
 (パケットフィルタの設定が、誰にでも書き換え可能になっていたら… やっぱり、危ないですよね(^^;;
 《 "/etc/rc…"というパス名で始まるファイルの、詳細情報を表示 》
$ ls -dl /etc/rc*[Enter]
-rw-r--r--  1 root  wheel   3753 May  1 15:56 /etc/rc
-rw-r--r--  1 root  wheel   4611 May  1 15:56 /etc/rc.bsdextended
-rw-r--r--  1 root  wheel    568 Aug  6 21:15 /etc/rc.conf ← FreeBSD のシステム設定ファイル
drwxr-xr-x  2 root  wheel   2560 Jun 22 03:49 /etc/rc.d
-rw-r--r--  1 root  wheel  13732 May  1 15:56 /etc/rc.firewall
-rw-r--r--  1 root  wheel   9473 May  1 15:56 /etc/rc.firewall6
-rw-r--r--  1 root  wheel   1598 Aug 12 21:29 /etc/rc.fw ← パケットフィルタの設定ファイル
-rw-r--r--  1 root  wheel  11418 May  1 15:56 /etc/rc.initdiskless
-rw-r--r--  1 root  wheel    114 Aug  6 21:15 /etc/rc.local
-rwxr-xr-x  1 root  wheel   2322 May  1 15:56 /etc/rc.resume
-rw-r--r--  1 root  wheel   5790 May  1 15:56 /etc/rc.sendmail
-rw-r--r--  1 root  wheel   3311 May  1 15:56 /etc/rc.shutdown
-rw-r--r--  1 root  wheel  36048 May  1 15:56 /etc/rc.subr
-rwxr-xr-x  1 root  wheel   2291 May  1 15:56 /etc/rc.suspend
$  
 /etc/rc.conf と、/etc/rc.fw が、「-rw-r--r--」、「root wheel」と表示されていれば、合格です(^^)


■ パケットフィルタの有効化

 パケットフィルタの設定ファイルが準備できたら、パケットフィルタを有効化する設定を行います。

 /etc/rc.conf に、次の3行を追加し、
 firewall_enable="YES"
 firewall_logging="YES"
 firewall_script="/etc/rc.fw"
 FreeBSD を一度、再起動します。
 (firewall_enable="YES" の設定で、FreeBSD の起動時に「ipfw.ko」という名前のカーネルモジュールが呼び出され、パケットフィルタが使えるようになります)
 《 FreeBSD を再起動する 》
# reboot[Enter]
 ● パケットフィルタの動作確認

 FreeBSD が再起動したら、パケットフィルタがきちんと設定されているか、確認します。
 《 パケットフィルタのルールを表示する 》
# ipfw list[Enter]
00100 allow ip from any to any via lo0
00200 deny ip from any to 127.0.0.0/8
00300 deny ip from 127.0.0.0/8 to any
00400 allow tcp from any to any established
00500 allow ip from any to any frag
00600 check-state
00700 deny tcp from any 137-139,445 to any
00800 deny tcp from any to any dst-port 137-139,445
00900 deny udp from any 137-139,445 to any
01000 deny udp from any to any dst-port 137-139,445
01100 allow udp from 192.168.1.0/24 to me dst-port 53 keep-state
01200 allow udp from 192.168.1.0/24 to me dst-port 123 keep-state
01300 allow tcp from 192.168.1.0/24 to me setup
01400 allow ip from 192.168.1.0/24 to me
01500 allow ip from me to 192.168.1.0/24
01600 allow udp from 192.168.1.0/24 to any dst-port 53 keep-state
01700 allow udp from 192.168.1.0/24 to any dst-port 123 keep-state
01800 allow tcp from 192.168.1.0/24 to any setup
01900 allow icmp from any to any in icmptypes 0,3,4,11,12
02000 allow icmp from any to any out icmptypes 3,4,8,11,12
02100 deny log ip from any to any
65535 deny ip from any to any
#  
 /etc/rc.fw で設定したものと、用語が多少違ってはいますが (allip と表示されていたり、dst-port が勝手に追加されているなど)、覚えのあるルールが全て表示されていれば、OK です。
65535番のルールは、ipfw -f flush でも消えないデフォルトのルールなので、気にしなくて OK です(^^;

 もし、間違いを見つけたら、/etc/rc.fw を修正した後、今度は、
 《 sh に /etc/rc.fw を読み込ませて実行させる 》
# sh /etc/rc.fw[Enter]
#  
 で、パケットフィルタのルールを書き換えることができます


 ここまで、うまくいっていれば、今度は ssh を使ってネットワーク経由で接続した後、パケットフィルタの働きぶりを見てみましよう。
 《 パケットフィルタのパケット情報をあわせて表示する 》
# ipfw -a list[Enter]
00100  36  3474 allow ip from any to any via lo0
00200   0     0 deny ip from any to 127.0.0.0/8
00300   0     0 deny ip from 127.0.0.0/8 to any
00400 692 63917 allow tcp from any to any established
00500   0     0 allow ip from any to any frag
00600   0     0 check-state
00700   0     0 deny tcp from any 137-139,445 to any
00800   0     0 deny tcp from any to any dst-port 137-139,445
00900  17  2000 deny udp from any 137-139,445 to any
01000   0     0 deny udp from any to any dst-port 137-139,445
01100   0     0 allow udp from 192.168.1.0/24 to me dst-port 53 keep-state
01200   0     0 allow udp from 192.168.1.0/24 to me dst-port 123 keep-state
01300   1    48 allow tcp from 192.168.1.0/24 to me setup
01400   0     0 allow ip from 192.168.1.0/24 to me
01500   0     0 allow ip from me to 192.168.1.0/24
01600  26  3879 allow udp from 192.168.1.0/24 to any dst-port 53 keep-state
01700 100  7600 allow udp from 192.168.1.0/24 to any dst-port 123 keep-state
01800   0     0 allow tcp from 192.168.1.0/24 to any setup
01900   0     0 allow icmp from any to any in icmptypes 0,3,4,11,12
02000   0     0 allow icmp from any to any out icmptypes 3,4,8,11,12
02100   0     0 deny ip from any to any
65535   0     0 deny ip from any to any
#  
 これは、ssh でログインして 10分ほど経ったときのものです。
 一応、解説しておくと、左端の数字がルール番号、2番目がルールにマッチしたパケット数、3番目が流れたパケットのバイト数で、

 00100番:FreeBSD 上のループバックインターフェイスを流れたパケット
      (中身は、ntpd から unbound への DNS 問い合わせと、その返答)
 00400番:接続が確立された後の TCP パケット
      (ssh を使った、Windows ~ FreeBSD 間の TCP 通信)
 00900番:Windows から発信された NetBIOS パケット
      (中身は、137/UDP と 138/UDP で、すべて拒否されました(^^;)
 01300番:LAN 内部からの TCP 接続要求パケット
      (Windows の ssh クライアントから発信されたもの)
 01600番:インターネットへの DNS 問い合わせ
      (unbound による DNS 問い合わせと、その返答)
 01700番:インターネットへの NTP 問い合わせ
      (ntpd による時刻問い合わせと、その返答)

 となります。

 ちなみに、00600番の check-state ルールにマッチしたパケットは、もとの動的ルール(1600番と1700番)のところに加算されています。

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

FreeBSD の省電力の設定(powerd を使う)

 powerd とは、CPU がアイドル状態の時に、CPU の動作クロックを下げることで、PC の消費電力を抑えてくれる、エコなデーモンです(^^)

 ちなみに、powerd はデーモンですが、サーバでもクライアントでもありません…(^^;;


■ 事前準備

 ありません。 強いていえば、マニュアルを読むくらい?
 《 powerd のマニュアルを読む 》
$ man powerd[Enter]
$  
 英語は苦手だ、という人は、こちらがお勧めです(^-^)

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

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


■ インストール

 powerd は、FreeBSD に初めから入っているので、改めてインストールする必要はありません。


■ powerd の設定

 powerd は、コマンドラインで動作の設定ができるので、設定ファイルを作る必要はありません。

 前述のマニュアルによると、特に何も指定しない場合は、

 powerd -a hiadaptive -b adaptive

 (AC電源使用時は、処理性能を重視したバランスモード(-a hiadaptive)、バッテリ駆動時は、省電力重視のバランスモード(-b adaptive))で動くようです。


■ powerd の起動

 例の通り、まずは手動で powerd を起動してみて、その効果を確認してみましょう。

 最初に、powerd を動かす前の CPU 動作クロックを確認しておきます。
 《 CPU 関連のシステム変数のうち、"freq" という言葉を含むものを表示 》
# sysctl dev.cpu | grep freq[Enter]
dev.cpu.0.freq: 1599 ← ここ
dev.cpu.0.freq_levels: 1599/-1 1399/-1 1199/-1 999/-1 799/-1 599/-1 399/-1 199/-1
#  
 うちのサーバの CPU、Atom 230 は、間違いなく全速力 (1599 = 約1.6GHz) で動いているようですね(^^)
 では、powerd を起動してみます。
 《 powerd を起動 》
# powerd -a adaptive[Enter]
#  
 ふたたび、CPU の動作クロックを表示させてみると…
# sysctl dev.cpu | grep freq[Enter]
dev.cpu.0.freq: 199 ← ここ
dev.cpu.0.freq_levels: 1599/-1 1399/-1 1199/-1 999/-1 799/-1 599/-1 399/-1 199/-1
#  
 今度は、199 = 約200MHz と、最初の 1/8 のスピードになってしまいました

 CPU の消費電力は、動作クロックに比例するので、これはつまり、消費電力も 1/8 になっているという計算ですね(^^;

 では、CPU に負荷を与えてみると…
 《 /usr/sbin ディレクトリにある全ファイルの SHA-256 ダイジェストを計算させる 》
# sha256 /usr/sbin/*  > dev/null ; sysctl dev.cpu | grep freq[Enter]
dev.cpu.0.freq: 1599 ← ここ
dev.cpu.0.freq_levels: 1599/-1 1399/-1 1199/-1 999/-1 799/-1 599/-1 399/-1 199/-1
#  
 …きちんと、CPU は全速力で動き出すようですね(^^)


■ FreeBSD 起動と同時に、powerd を起動させる

 powerd は、FreeBSD に初めから入っているので、例の通り、/etc/rc.conf に、次の1行を追加すれば、FreeBSD の起動時に、自動的に起動します。
 powerd_enable="YES"
 ただし、私のわがままとして(^^;;FreeBSD が起動してから 5分後に powerd を起動させたいので、今回は、別の手段で起動させることにします。


 Windows ならば、スタートアップフォルダに、プログラムのショートカットを入れておけば、好きなプログラムを Windows の起動と一緒に起動させることができますが、FreeBSD の場合はというと…

 いくつか方法はありますが、行儀のよい(^^;方法としては、
(1) /etc/rc.local に、プログラムの起動コマンドを書いておく
(2) /usr/local/etc/rc.d ディレクトリに、起動/停止用のスクリプトを置いておく
 の2種類があります。

 powerd は、基本的に、起動したら、停止する必要はないプログラムなので、今回は、(1) の方法を採用します。

● powerd を起動させる設定

 次のような内容の /etc/rc.local を作ります。
#!/bin/sh

# Run powerd after 5 min.
( /bin/sleep 300 ; /usr/sbin/powerd -a adaptive ) &
【解説】

01行目:
 スクリプトを解釈、実行するプログラムの指定。

 今回は、一番普通に、/bin/sh を使います。

04行目:
 ここが、今回のメインです。

 まず、括弧の中の説明ですが、

 /bin/sleep 300 で、300秒間なにもせずに、時間が経過するのを待ちます。
 その後、目的の /usr/sbin/powerd -a adaptive が実行されます。
 「/bin/sleep 300」 と 「/usr/sbin/powerd -a adaptive」 の間にある「;」は、複数のコマンドを1行にまとめて書くための、ちょっとしたワザです(^-^)

 これらを括弧で囲むことにより、ひとまりのプログラムとみなし、これにバックグラウンドでの実行を指示する「&」を付けることで、「5分が経過した後に powerd を実行する」処理を実現しています。

/etc/rc.local の内容がこれだけなら、実は、括弧で囲む必要も、& でバックグラウンド実行をさせる必要もないのですが、この後ろに別の処理が続く場合には、これらがないと、これ以降の処理 全てが、5 分間 待たされる羽目になってしまいます(^^;。)

 これで、次回の FreeBSD 起動時から、powerd が(5分遅れで)自動的に起動するようになります。

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

FreeBSD の時刻を合わせる(ntpd の設定)

 ntpdNTPデーモン)は、インターネット上の NTPサーバ時刻配信サーバ)から時刻情報を受け取って、PC の時計を合わせてくれるソフトです。

 PC の時間が正確だと、それだけで嬉しい…というだけでなく(^^;、何かいいことがあるかもしれないので、FreeBSD をインストールしたら、真っ先に動かしておきましょう(^^)


■ 事前準備

 最初に、時刻をもらってくる、接続先の NTPサーバ を決めます。

 契約しているプロバイダが NTPサーバを公開していれば、普通はそれを使うのが一番良いのですが、そうでない場合には、一般に公開されている NTPサーバを探すことになります。

 私は、mfeed の NTPサーバを使わせてもらっています。

 ◆ インターネットマルチフィード時刻情報サービス for Public: http://www.jst.mfeed.ad.jp/


■ ntpd のインストール

 …もとから FreeBSD に入っているので、改めてインストールする必要はありません(^^;


■ 設定ファイルの作成

 ntpd の設定ファイルは、/etc/ntp.conf (ntpd.conf ではない(^^;)なので、これを新しく作成します。
#       /etc/ntp.conf

server  ntp1.xxx.yyy.jp    maxpoll 14
server  ntp2.xxx.yyy.jp    maxpoll 14
server  ntp3.xxx.yyy.jp    maxpoll 14

logconfig =syncstatus +sysevents +clockall

restrict  default nomodify noquery
restrict  192.168.12.0 mask 255.255.255.0 nomodify
restrict  127.0.0.1
● 解説

03行目:server ntp1.xxx.yyy.jp     maxpoll 14
04行目:server ntp2.xxx.yyy.jp     maxpoll 14
05行目:server ntp3.xxx.yyy.jp     maxpoll 14

 時刻情報をもらってくる、インターネット上の時刻配信サーバ指定します
 server 行は、複数書くこともでき、その場合には、その中から、時間合わせに最も「適した」時刻配信サーバが1つ選ばれます。

 後ろの maxpoll は、時刻配信サーバへの接続間隔を設定します。
 ntpd は、起動直後は短い間隔で、時刻配信サーバへ時刻情報をもらいにいきますが、徐々に時刻配信サーバへ接続する間隔を延ばしていき、最終的には maxpoll で設定した間隔(この場合は、2^14 = 16384秒 = 約4.5時間)ごとに時刻情報をもらうようになります。

 ntpd には、単独で PC の時計のずれを補正する機能がありますし、なにより、時刻配信サーバに無駄な負荷をかけてはいけないので、あまり短い接続間隔を設定するのはやめましよう(^^;

07行目:logconfig =syncstatus +sysevents +clockall

 ログに何を記録するかを指定します。(ま、適当に…(^-^;ヾ(^^;ぉぃ。)

09~11行目:

 アクセス制御の設定です。

 ntpd は、自分自身が時刻配信サーバになることもできますが、その際、どの PC (あるいはネットワーク)から、どのような種類のアクセスを許可するかを設定します。

09行目:restrict  default nomodify noquery

 特に指定のないホストからは、時刻変更(modify)も時刻問い合わせ(query)も受け付けません。
 以前は、
 restrict  default ignore
 と書いて OK だったのですが、現在は、こう書くと、時刻配信サーバへも接続できなくなってしまうようです(^^;

10行目:restrict  192.168.1.0 mask 255.255.255.0 nomodify
 LAN 内の PC(アドレス:192.168.1.0/24)からは、時刻変更の要求を受け付けません。
 ただし、時刻の問い合わせは(禁止していないので)受け付けます。

11行目:restrict  127.0.0.1
 自分自身(アドレス:127.0.0.1)からは、時刻変更も時刻問い合わせも受け付けます。


■ ntpd の起動

 確認のため、まず、手動で ntpd を起動してみます。
 《 ntpd を起動 》
# ntpd -c /etc/ntp.conf -p /var/run/ntpd.pid -f /var/db/ntpd.drift[Enter]
#  
 続いて、ntpd の制御用に準備されている ntpq というプログラムを使って、ntpd の状態を表示させてみます。
 《 ntpd の状態を表示 》
$ ntpq -p[Enter]
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
 ntp1.xxx.yyy.jp. .STEP.         16 u  199   64    0    0.000    0.000   0.002
 ntp2.xxx.yyy.jp. .STEP.         16 u  122   64    0    0.000    0.000   0.002
 ntp3.xxx.yyy.jp. .STEP.         16 u  139   64    0    0.000    0.000   0.002
$  
 ここで、1分程度待っても全ての数字が 0 のままならば、ntpd が NTPサーバに接続できていないので、/etc/ntp.conf に間違いがないかや、パケットフィルタの設定を見直すことになります(^^;;

 5分ほどしてから、もう一度 ntpd の状態を表示させてみて、
 《 再び ntpd の状態を表示 》
$ ntpq -p[Enter]
     remote           refid      st t when poll reach   delay   offset  jitter
==============================================================================
+ntp1.xxx.yyy.jp. 210.173.xx.yy   2 u   41  128  377   36.412   16.900   5.649
*ntp2.xxx.yyy.jp. 210.173.xx.yy   2 u   48  128  377   36.617   10.625   5.973 ← これ
+ntp3.xxx.yyy.jp. 210.173.xx.yy   2 u  113  128  377   36.646    9.725   6.875
$  
 と、左端に「*」のマークが付けば、NTPサーバとの同期が完了し、PC の時計の自動調整が行われます
 このとき、ログには、次のような記録が残ります。
 《 システムログを確認 》
$ tail /var/log/messages[Enter]
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Aug  6 21:00:00 thyme ntpd[537] time reset -3.625633 s
Aug  6 21:00:00 thyme ntpd[537] kernel time sync status change 2001
$  


■ FreeBSD 起動と同時に、ntpd を起動する

 ntpd は、FreeBSD に付属しているプログラムなので、FreeBSD の流儀にのっとり、/etc/rc/conf に、
ntpd_enable="YES"
 という1行を書き足して、FreeBSD を再起動すれば、ntpd が自動的に起動します。

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

« 2009年7月 | トップページ | 2009年9月 »