以下のテキストは、執筆時当時の情報を元に書いたものであり、 現在の情勢にそぐわないことを含む場合があるので注意されたい。 また、テキストは最終提出原稿で校正を経る前のものなので、実際にUNIXUSER 本誌に記載されたものとは異なる。誤字脱字等そのままである。
致命的な誤り以外は加筆修正等は行なわないので情報の鮮度に気をつけつつ 利用して欲しい。
→目次
PartIII ソフトウェアによるセキュリティ・チューニング 各種PC-UNIXの最近のリリースでは、初期インストール状態のセキュリティを考 慮する度合がどんどん高まっている。今回紹介する tcp_wrappers もその働きを 一役買っていて、NetBSD(1.3以降)・FreeBSD(3.2R以降)ではネットワーク・サー ビス・デーモンにデフォルトでその機構が組み込まれて「守りの固い」環境を作 る労力がかなり軽減された。 また、安全に遠隔操作をするための ssh は、利用規約の関係からOS標準装備に はなってはいないものの、既に標準的なセキュリティ・ツールとしての地位を獲 得している。ところが、「管理者から強制されていやいや…」使っているなど、 その便利な部分を活用せずにいる利用者も多い。 ここでは「安全かつ快適に」を目標に、セキュリティを高める利用方法について 解説する。 ■tcp_wrappers tcp_wrappers は各種ネットワーク・サービス・デーモン・プログラム の起動を包み(wrap)込み、接続要求を行なって来た相手のIPアドレスを もとに接続許可不許可などの動作を定義できるツールである。同様のも のに ucspi-tcp(tcpserver)[*1] があり、これは最大起動プロセス数制 限を始めとするきめこまやかな動作定義オプションが用意されていて、 DoSアタック(Denial of Service:サービス不能に陥れる不当過剰接続) にも、より強いといわれている。しかしこちらは接続制限だけに特化さ れたものではないので初めて触れる人にとっては機能が豊富すぎて分か りづらいと感じる可能性がある。また接続制限用の設定ファイルはテキ スト形式のままでは利用できず、専用プログラムを利用してバイナリ形 式のファイルに変換する必要がある。makeを利用するなど工夫次第で負 担を軽減できるものではあるが、やはり変換の手間がないもののほうが 管理時の負担と混乱が少なくて済むということは否めない。また、 ucspi-tcpの場合は inetd を一切利用しない方式なのでOSの標準として 採用するには、利用者にとって変化が大きすぎるきらいがある。これに 対し tcp_wrappers は inetd をこれまで通りの方法で利用できるので、 とくに利用することを意識しなくても問題なく使える。 以上のような総合的な条件をふまえて、FreeBSDに tcp_wrappers が標 準装備となったのではなかろうか。いずれにしても、セキュリティ向上 のためのツールがOS標準となっていくのは歓迎すべき流れである。これ を機会に、全てのUNIX管理者がネットワーク・サービスのアクセス制御 に意識を向けてもらえることを祈り本稿で解説する。 ★脚注*1★------------------------------------------------------- ftp://koobera.math.uic.edu/www/ucspi-tcp.html ----------------------------------------------------------------- ●tcp_wrappersの導入 さて、NetBSD 1.3以降およびFreeBSD 3.2R以降を使っている場合は既に inetdに tcp_wrappers のライブラリ(libwrap)が組み込まれているので 個人でインストールする必要はないが、組み込みになっていないバージョ ンを併用している人のために簡単にインストール時の要点を説明してお こう。たとえば FreeBSD 3.x系と FreeBSD 2.2.8R の両方で tcp_wrappers によるフィルタリングを行ないたいというような場合、 3.x 系で組み込まれているtcp_wrappers のコンフィギュレーションに 合わせておくと運用がスムーズに行なえる。以下で説明する設定値は NetBSD、FreeBSD共通のものなのでどちらの場合でも適用できる。 ・コンパイル tcp_wrappers_7.6.tar.gz が執筆時の最新版で、これはFreeBSDのミラー サイトなど多くのftpサイトで見付かるのでそれを入手する。アーカイ ブを解いてそのディレクトリに移動しておもむろに make と叩くと、 makeのときのパラメータの与え方と対応プラットフォーム一覧が表示さ れる。NetBSD/FreeBSDで導入された tcp_wrappers では PROCESS_OPTIONS オプションが指定されているので自身でmakeする場合 にもこれに合わせる。本来、接続許可定義は /etc/hosts.allow, 拒否 定義は /etc/hosts.deny と二つのファイルに分けて書かなければいけ ないのだが、PROCESS_OPTIONS オプションをつけることにより、 hosts.allow ファイルだけで一元管理できるようになるほか、拡張表記 を使えるようになる。またコンパイル変数 REAL_DAEMON_DIR は本物の サービス・デーモン・プログラムをしまう場所であるので、以下の例を 参考に適切なディレクトリを指定する。make は、たとえば以下のよう に行なう。 (NetBSDの場合)# make READ_DAEMON_DIR=/usr/libexec/realdir netbsd (FreeBSDの場合)# make READ_DAEMON_DIR=/usr/libexec/realdir freebsd ・インストール 残念ながら make install で一発インストール、という訳にはいかない。 tcp_wrappers の中核である tcpd プログラムを /usr/libexec にコピー する(実際はinetd.confで調整すればどこにコピーしても良い)。tcpd以 外にいくつか実行ファイルができているがこれは読者の判断で管理者用 のコマンドを置くべき場所にコピーすれば良い。 コマンドのインストールが終わったら、そのままの /etc/inetd.conf で tcpd が起動するようにファイルの移動をする。たとえば、 inetd.conf の ftpd に関する部分が ftp stream tcp nowait root /usr/libexec/ftpd ftpd -ll だとしたら、/usr/libexec/ftpd がtcpdになるようにし、本物のftpdは REAL_DAEMON_DIRで指定したディレクトリに移動する。 # cd /usr/libexec # mkdir realdir # mv ftpd realdir ; ln tcpd ftpd こうすることで 3.x 系のホストのものと同一形式で /etc/inetd.conf, /etc/hosts.allow を運用することができる。 以上の作業で tcp_wrappers の設定環境が NetBSD 1.3以降、FreeBSD 3.2R以降と揃ったことになる。 ●/etc/hosts.allowの設定 標準インストール状態のtcpdは接続制限設定ファイルとして /etc/hosts.allow と /etc/hosts.deny を参照する。前者に書いたもの は、アクション記述を省略したときのデフォルトの動作が「接続許可」 で、後者に書いたもののデフォルト動作が「接続拒否」となる点を除い て全く同じ書式での記述となる。二つのファイルが存在した場合、 hosts.allow, hosts.deny の順で読み込まれ、マッチする行があった時 点で解釈を終えるので、「hosts.denyをいじっていたが実は hosts.allowのほうでマッチしていた」などのミスには気をつけなけれ ばならない。とくに、複数人で管理しているような場合はファイルの使 い分けポリシーを徹底周知しておかないと余計な混乱を来たす恐れがあ るので、個人的には hosts.allow ただ一つだけで運用するほうが混乱 が少なくて良いのではないかと考えている。これが理由かどうかは定か でないが、NetBSD・FreeBSDのデフォルト設定でも hosts.allow のみを 利用している。それにならい、ここでも hosts.allow のみを用いると いう前提で説明する。 ・hosts.allow の書式 hosts.allow には、1行1エントリでデーモン・プログラム毎の接続許可 を記述する。行末に\を置くと次の行が継続行と見なされる。基本的な 書式は、:(コロン)記号をフィールド句切りとする デーモン(のリスト) : クライアント・アドレス(のリスト) : \ オプション : オプション .... というものである。第1、第2フィールドはスペースまたは ,(カンマ) で区切って複数の要素を列挙することができる。第1フィールド「デー モン」の部分には inetd.conf で起動プログラムとして記述したサービ ス・デーモン・プログラムのベースネーム(ディレクトリ名を取り除い た部分)を、第2フィールド「クライアント・アドレス」の部分にはその サービスを利用しに来たクライアント・ホストのアドレスを記述する。 アドレス指定はホスト名、ドメイン名、IPアドレス(netmask指定可)の いずれでも書くことができる。第3フィールド以降に任意個数書ける 「オプション」にはデーモンとアドレスの組み合わせにマッチした接続 に対するアクションを書くことができる。省略すると、単に接続許可を 与えるという意味のキーワード ALLOW を書いたのと同じ効果となる (hosts.allow に書かれる場合のデフォルトアクション)。 アドレスの部分には、先頭か末尾をピリオドにすることによるワイルド カード指定もできる。具体例を見よう。 rshd rlogind telnetd : .my.domain.com mypc ftpd : .my.domain.com 10.0. ALL : ALL : DENY 上記の例の1行目では rshd, rlogind, telnetd はDNS空間的に my.domain.com に属するホスト全て、および、mypcというホスト(hosts データベースに名前が登録されている場合)に対する接続を許可し、2行 目では ftpd は my.domain.com に属するホスト全て、および、ネット ワークアドレス10.0. のネットワークにあるホスト全てからのアクセス を許可することになる。また、IPアドレスのマッチングは 10.0.0.0/255.255.0.0 のようにnetmaskを使って指示することもできる。 そして最後の3行目に登場するキーワード ALL は、第1,第2両フィール ド共通で使えるワイルドカードで「つねにマッチする」という意味をも つので、3行目のこの記述により全てのクライアントからきた(tcpd経由 の)全てのデーモンに対する接続要求が拒否(DENY)される。 hosts.allow の最後にこれを書いておかないと、あらゆる接続を許可し てしまうことになるので注意する。 また、アドレス部分を User@Address のように書くと、IDENTプロトコ ルによって得たユーザ名とのマッチングが行なえる。 ・ワイルドカード 第2フィールドではALL以外に以下のワイルドカードを利用できる。 LOCAL - ホスト名がローカルな名前(ピリオドを含まない)だった場合に マッチする。hosts データベースに(ピリオド無しの)ホスト名 だけのエントリがあるようなホストはこれに相当する。 UNKNOWN - 接続してきたユーザが不明、または接続して来たホストのIP アドレスかホスト名が不明な場合にマッチする。ネーム・サー バが不調なときもマッチしてしまうので注意する。 KNOWN - UNKNOWNと逆でホスト名やユーザ名が引けたときにマッチする。 PARANOID - デフォルトではこのワイルドカードは使えない。意味とし ては、IPアドレスから逆引きして得られたホスト名でさら にDNSを引き、得られたIPアドレスが最初のものと一致しな い場合にマッチする。いわゆる「DNSのうそつき問題」を排 除するワイルドカード。しかしデフォルト設定でコンパイ ルされたtcpdでは hosts.allow の解釈に入る以前に PARANOIDなクライアントからの接続は拒否してしまう。 tcpdの吐き出すログ(両BSDの場合デフォルトでは /var/log/maillog)を観察し、"host name/address mismatch" というメッセージが出ていた場合は、相手ホス トのIPアドレスのDNS登録状態を確認してみる。クラックを 試みているかに見える怪しいホストである可能性もあるが、 現実にはうそつきDNSが好ましくないことだということを知 らずにDNSに登録しているサイト管理者による誤った設定で あることが多い。Linuxの各ディストリビューション /NetBSD/FreeBSDいずれのシステムもtcp_wrappersを標準装 備するようになった今、うそつきDNS登録をしているホスト はあらゆるサービスの接続に対して門前払いを浴びる可能 性が日に日に高まるのではないかと思う。知合いのいるド メインからの接続が address mismatch により失敗してい るような痕跡を発見したら相手の管理者に知らせてあげる と良い。 EXCEPT - これはワイルドカードではないが、これまで説明したワイル ドカードによる記法と組み合わせて「ただし〜以外」という条件を設定 するために使う。 ALL : .my.office.com EXCEPT dialup.my.office.com とすると、my.office.comドメイン所属下のあらゆるマシンの接続を許 可するが dialup.my.office.com だけは除外することになる。 ・オプション 第3フィールド以降で使える「オプション」では非常に多くの動作を指 示できる。それら全てに関しては man hosts_options(5) を見てもらう として、ここでは実用上必要な項目について説明する。 allow - 接続を許可する。 deny - 接続を拒否する。マッチしたサービスに対しdenyが見付かると それ以後の記述が無視されるので、必ずdenyは最後のオプションとして 書くようにする。 spawn ShellCommand - `ShellCommand' を実行する。以下の ようにすると許可の無い場所からtelnetを試みて来た事実を管理者に知 らせることができる(%dと%hについては後述)。 telnetd : .telnet-ok.domain.com : allow telnetd : ALL : \ spawn (/usr/bin/mail -s %d-%h root)& : deny setenv Variable Value - 環境変数 Variable に Value をセットして から本来のサービス・デーモン・プログラムを起動する。qmailでのリ レー配送許可の決定や、POP before SMTP などはこれを使うことでシン プルに実現している。 なお、上記のオプションの記述中には「%展開」が利用できる。オプショ ン中に書いた `%英字' は接続して来たクライアントの情報により、[表 1]のような文字列に展開される。 ★[表1]★ ----------------------------------------------------------------- %a (%A) クライアント(サーバ)のIPアドレス %c クライアント情報(取得できる情報量により user@host, user@address, host, addressいずれかの形になる) %d デーモンのプロセス名(argv[0]) %h (%H) クライアント(サーバ)のホスト名 (名前が引けないときは アドレスが入る) %n (%N) クライアント(サーバ)のホスト名(名前が引けないときは "unknown" または "paranoid" が入る) %p デーモン・プログラムのプロセスID %s サーバ情報(取得できる情報量により daemon@host, daemon@address, daemon いずれかの形になる) %u クライアントのユーザ名 (不明時は"unknown") %% %自身 ----------------------------------------------------------------- ●hosts.allowの設定確認 tcp_wrappersには hosts.allow に書いた設定を検査するツールが付属 している。tcpdchk コマンドは hosts.allow の文法的誤りや、潜在的 におきそうな誤りを警告してくれる。また、tcpdmatch コマンドは # tcpdmatch デーモン名 クライアントホスト名(またはアドレス) のように起動することで、実際にそのような接続があったときに、どの ようなアクションが取られるかを調べてくれる。二つのコマンドを組み 合わせて使うことで hosts.allow を期待通りの設定にすることができ る。実際に外部から接続実験をしてみて、接続の許可不許可が正しく行 なえることを確認したら見事導入完了である。 ・FreeBSD 3.2R/3.3R における注意点 tcpdchk, tcpdmatch はともに /etc/inetd.conf を見てtcpdの制御が及 ぶデーモンかどれかを判断する。ところが FreeBSD 3.3R/3.3R では、 各デーモンに libwrap を組み込んでいるため inetd.conf にはtcpdと いう単語が含まれないことになる。そのため、tcpdchk ではチェックす べき項目は無いと判断されて、文法ミスの指摘などをしてもらえない。 また、hosts.allow でドメイン名でクライアントのパターンを書いた場 合、tcpdmatch にIPアドレスを指定して検査しても正しい結果を返して くれない。パターンをIPアドレスで書いておけば常に正しい結果を返し てくれるので、tcpdmatchを使いたい場合はIPアドレス・ベースで記述 しなければならない。 さらに、portmap(NFSのアクセス制御を行なう)にもlibwrapが組み込ま れていて hosts.allow を参照するのだが、portmapに関することだけは 必ずクライアントのパターンをIPアドレス・ベースで書かなければなら ないという「仕様」がある。3.3Rの標準の hosts.allow にはこのこと が明記されるたので気がつく人もいるかと思うが、3.2Rを使っている人 は気をつけて欲しい。 もうひとつ、tcp_wrappersの標準設定自体の問題ではないが、3.2Rには inetd に HUP シグナルを送っても inetd.conf の読み直しがうまくい かない(一見うまくいったように見える)というバグがあった。 inetd.conf に追加したデーモンをtcpdで制御できないという事態に遭 遇したらinetdを再起動してみると良いかもしれない(3.3Rにアップグレー ドしてしまうほうが良いだろう:-)。 以上のように、FreeBSD 3.2R/3.3R には tcp_wrappers や inetd の設 定に精通しているほど陥りやすい罠があるので注意して欲しい。実際筆 者を含め身近なところで数人がこの迷宮に入り込み数時間を費してしまっ た…。 NetBSD ではlibwrap組み込みであることを考慮した tcpdchk が入って いるので上記のトラブルには遭わずに済む。 ■sshを使いこなす 旧来UNIX系OSで遠隔ホストに対するログインや、ファイルのコピーをす るときに広く用いられて来た rsh, rlogin, rcp などのr系コマンドの 置き換えとして、通信を暗号化してより安全に作業できるようにしたも のがssh(Secure Shell)である。 sshの一番大きな目的はその名が示す通り遠隔ホスト操作時のセキュリ ティを確保することである。しかしそれだけではないところにsshのす ごさがある。UNIX系OS全般で使えるセキュリティツールにはssh以外に もいくつか著明なものが公開されているが、sshがここまで広く普及し たのはその付加的利便性にあると考える。筆者などは使い始めた当初、 それまでrshを使うためにリモートホストにいちいち~/.rhostsを置いて いたような作業が、sshならパスワードを打てばいつでもリモートコマ ンドの呼出ができるというそれだけのことで幸せに感じていた。もちろ んそれだけではなく、 - Xクライアントの安全なリモート実行 - 圧縮機能による通信の効率化(-Cオプション) - 任意のポートのssh伝送路への迂回機能(ポートフォワーディング: -R, -Lオプション) のように接続環境の厳しさを緩和するための機能など、セキュリティ以 外の面でも有効な機能を持っているのでこれらを十分に活用して欲しい。 ●libwrapつきでのインストール 基本的に「./configure 一発」でうまくいくので、基本的なインストー ルに関しては解説する必要はなかろう。しかし、せっかくFreeBSDで tcp_wrappers が標準となったのだから、それに見合った設定でインス トールしよう。sshは tcp_wrappers のアクセス制御ライブラリ (libwrap)の組み込み利用に対応している。/usr/lib/ ディレクトリに libwrap* ファイルがあることが確認できたら、configure スクリプト に--with-libwrap オプションを与え、 # ./configure --with-libwrap=/usr/lib # make && make install のようにすれば良い。また、tcp_wrappersを自分でインストールした場 合は、libwrap.aをインストールしたディレクトリを指定すれば良い。 この設定でコンパイルされたsshdは、/etc/hosts.allow によるアクセ ス制限が可能になるので、sshプロトコルによる接続を許すホストを限 定するなどのことが可能となる。 ●RSA認証を使おう 一般ユーザとして最初にsshを使う場合でも、sshは特に事前準備をする ことなく、rshコマンドと全く同じ操作感で使える。準備無しで使える 点もsshの良さでこの敷居の低さが大きな普及にもつながった。公開鍵 方式を使うより安全なRSA認証を利用するには少しばかりの事前準備が いる。その手間があるせいでRSA認証を利用していないユーザもいるか もしれないが、実はssh-agentを上手に利用することでこれまでより楽 にリモートマシンへの出入りが可能になる。 ・sshのRSA認証の仕組み ここでいう仕組みとは、公開鍵方式のアルゴリズムのことではなく、公 開鍵方式を遠隔ログインの認証方法としてどう適用しているかのことで ある。これを理解しておくとRSA認証を効果的に利用できる。rloginで 利用する一般的なパスワードによるログインの認証は、基本的にログイ ン先のホストが、その場に保存してあるパスワードファイルが絶対的存 在であり、ユーザの入力したパスワードがそれと一致すれば認証通過と なる。つまり、パスワードだけ知っていればどのホストからもログイン できる。 sshによるRSA認証ログインは情報の保管場所と形態がかなり違う。公開 鍵はログイン先ホストのファイルに、秘密鍵はローカルホストのファイ ルに、そして秘密鍵を取り出すパスフレーズはユーザの頭の中にある。 これらの三つが正しく組み合わされないと認証通過とならないので、パ スフレーズだけ手に入れた第三者が別のホストから認証通過しようとし てもそれはできない。つまり、利用者がコンソールで使っているホスト と覚えているパスフレーズの組合せが認証通過の条件となるので、利用 者がログインしたままコンソールを離れない限り、RSA認証を乗っ取る ことはできない[*2]。 ★脚注*2★------------------------------------------------------- もちろん正攻法で秘密鍵を破られたら駄目だが、あと1〜2年は大丈夫? ----------------------------------------------------------------- もっともデフォルト設定のsshはRSA認証の条件が揃っていないときは自 動的に旧来のパスワード認証に移行するので最終的にはUNIXパスワード の安全性に落ち着くのだが、なぜここでRSA認証の優位性を説明したか というと、次項で説明するssh-agentの利用に抵抗を感じる人が意外に 多いと感じるからである。ssh-agentはパスフレーズをユーザの代わり に接続先ホストのsshdに送り込んでくれるエージェント・プログラムだ が、このような「パスワードの類をコンピュータに覚えさせておく」行 為は、厳格な人には気が進まないことである場合が多い。しかし、先述 したようにRSA 認証の実質的安全性の高さゆえ「うかつにログインした ままコンソールを放置しない」ことの守れる人なら、ssh-agentで楽を しても問題はないように思う。むしろ毎回のパスフレーズ入力負担を軽 減する分、より強固な(長い)パスフレーズにしておけば総体的安全性の 増加につながる。なお、RSA認証は /etc/sshd_config において RSAAuthentication yes と設定されている場合に利用できる。デフォルト状態でインストールし たsshであれば yes になっているはずであるが、もし no になっていた 場合はこれを修正してsshdを再起動する。その他の認証方法の許可負許 可の設定も /etc/sshd_config で行なえるので、詳細は man sshd(8) を参照のこと。 ・キーを作る RSA認証用の公開鍵と秘密鍵は ssh-keygen コマンドで作成する。この 作業は、コンソールとして利用するホストにつき一回だけやれば良い (厳密には利用するホームディレクトリにつき一回)。 % ssh-keygen するとそのときの環境用の鍵を生成し、最後に秘密鍵を守るためのパス フレーズの入力を促してくるので、できるだけ長い自分だけにしか思い 付かない文章を二度入れる。すると ~/.ssh/ ディレクトリに秘密鍵 (identity)と公開鍵(identity.pub)ができる。この公開鍵を接続先とな るホストに置いてやれば準備が完了する。手段は何通りもあるが、たと えば次のようにすると楽に置くことができる[*3]。 % cat ~/.ssh/identity.pub | \ ssh remotehost 'cat >> ~/.ssh/authorized_keys' ★脚注*3★------------------------------------------------------- remotehostに ~/.ssh/ ディレクトリがまだできていないときにはエラー となってしまうが、このようなときは一度remotehosにこれまで通りの 方法でログインし、そこからどこかのホストに向かってsshログインを 試みるのが手っ取り早い。 ----------------------------------------------------------------- 準備ができたら実際にログインしてみよう。 % ssh remotehost Enter passphrase for RSA key 'user@your.domain.com': このようにパスフレーズを求めるプロンプトが表示されたら設定は成功 である。もしこれまでのように % ssh remotehost user@remotehost's passwd: と通常パスワード入力を求められた場合は、作り忘れ、転送し忘れのファ イルがないか確認する。 ・ssh-agentの利用 ssh-agent の起動方法にはいくつかのパターンがあるが、ここではX環 境で利用している場合にもっとも効果的と思われる方法を紹介する。通 常Xを起動するときには xinit あるいは startx コマンドを利用してい るであろう。そのかわりに % ssh-agent xinit (あるいは ssh-agent startx) のように起動する。これで、起動したX環境下のプロセス全てが ssh-agentと交信できる状態で起動する。具体的には、環境変数 SSH_AUTH_SOCK にssh-agent プログラムの作成するソケットファイルの フルパス名が代入された状態で立ち上がる。起動直後の状態は、パスフ レーズ未登録のエージェントが常駐しているだけなので、これにパスフ レーズを教えてやる必要がある。常駐エージェントと交信してパスフレー ズの登録・削除を行なうのが ssh-add コマンドである。上記のように ssh-agent の子プロセスとしてXを起動したのであれば ~/.xinitrc の 先頭のほうに ssh-add < /dev/null と書いておくと良かろう。図2のようなウィンドウが現れるので、 ★図2 「ssh-addのパスフレーズ入力ウィンドウ」 askpass.gif パスフレーズをタイプする。キータイプとともに青い部分が緑に変わっ ていくので、「これでは文字数が分かってしまうではないか!」と不満 を感じる人がいるかもしれないが、文字数が分かったくらいで推測され てしまうようなパスフレーズ[*4]をつけてはいけないという教育的仕様 だと筆者は信じている:-)。 ★脚注*4★------------------------------------------------------- そのようなものはパスフレーズとは呼べない。 ----------------------------------------------------------------- パスフレーズを入力せずESCを押すとエージェントへの登録は行なわれ ずに終了するが、あとでシェル上でssh-addを起動すればいつでもパス フレーズの登録ができる。登録されているかどうかは % ssh-add -l によって確認できる。登録されている状態で別のホストにsshログイン してみよう。見事パスフレーズを代理で送り込んでくれていたら設定成 功である。さらに、ログイン先ホストからまた別のホストにsshログイ ンを試みて、そのホストが公開鍵を保持したホストならこれもまた代理 でパスフレーズを送ってもらえることを確認する。少々ややこしいが、 sshは図3のようにssh-agentとの交信用ソケットをログイン先にまで延 ばしてくれる。ログイン先でssh-addを起動すると、host-1 の ssh-agentと交信することになるので、ログイン先あちらこちらで ssh-agent を起動する必要は全くない。 ★図3★ +---------+ +------------------------------+ | host-1 |----ssh--->| remotehost-1 | |ssh-agent|~~~~~~~~~~~|~host-1のagentに通じたソケット| +---------+ +------------------------------+ ||ssh +------------------------------+ | remotehost-2 | |~host-1のagentに通じたソケット| +------------------------------+ また X の親プロセスとして起動した ssh-agent は、Xの終了とともに それ自身も終了する。 ・端末のロック 先に述べた通りssh-agentにパスフレーズを覚えさせたまま席を離れる のは危険である。もっとも良いのは全てログアウトして退席することで あろうが、危険度と手間の兼ね合いでxlock程度の安全性で良い[*5]環 境であればリスト1のようなシェルスクリプトを利用することで、 ssh-add を端末ロック・プログラムとして働かせることができて便利で ある。 ★脚注*5★------------------------------------------------------- ちょっとした用事や悪戯で触ろうとすることは防止するが、緊急度の高 いときには強制終了させる手段がいくつか残されている、という程度。 ----------------------------------------------------------------- ★リスト1 [ssh-lock.sh]★ +---------------------------------------------------------------------------- |#!/bin/sh |if [ "$DISPLAY" = "" ]; then | echo Cannot lock terminal | echo Use this lock script in X environment | exit 1 |fi | |# 無視したいシグナルを列挙する (/usr/include/sys/signal.h) |trap '' 2 3 | |ssh-add -D #現在登録されているパスフレーズを全て消去 |while ! ssh-add < /dev/null #ssh-addでパスフレーズが入るまで繰り返す |do | echo "Invalid passphrase." | echo "Try again." |done |ssh-add -l +---------------------------------------------------------------------------- ●Port Forwardingを活用する sshは遠隔ログインでの操作を暗号化するだけでなく、任意のポート番 号のサービスを、ssh自身の暗号化通信路に迂回させることができる。 これを利用すると、平文パスワードを The Internet に流すことを回避 できる。さらに安全面の利点だけでなく、sshで開いた圧縮通信路に別 プロトコルの通信を乗せるなど、効率面での利点もあるので是非活用し たい。現実問題として、管理しているサーバマシンへのパスワードを必 要とするアクセスは全て Port Forwarding を利用させることを徹底さ せたいと思いつつも、sshに関する情報をもたないWindows利用者に説明 するための資料などが用意できず、結局一部のプロトコルはパスワード 素通しでの運用に甘んじているケースは多いのではなかろうか。あるい は純粋に、普段FreeBSDとWindowsを両方使っていて、FreeBSDマシンを サーバと見立ててWindowsマシンから利用しているという読者の割合が 大きいのではなかろうか。 そのような事情もふまえ、ここではUNIX用クライアントソフトウェアだ けでなく、Windowsでの Port Forwarding の活用方法についても解説する。 ・Port Forwardingの設定 【UNIXの場合】 ローカルホストの任意のポートをリモートホストの特定のポートにフォ ワードするときには ssh の -L オプションを使う。たとえばlocalhost の8110番をremotehostの110番(POP3)に繋げたいときは次のようにsshロ グインすれば良い。 % ssh -L 8110:remotehost.hogehoge.jp:110 remotehost.hogehoge.jp -Lオプションに与えるホストと、ログイン先ホストはそれぞれが直接通 信できる関係ならば別々でも構わない。 % ssh -L 8110:remotehost.hogehoge.jp:110 anotherhost.hogehoge.jp この場合は anotherhost と remotehost 間のポート110番の通信は暗号 化されないことに注意する。-Lオプションは何個でも指定できて、一つ のsshログインセッションで複数の Port Forwarding を設定することが できる。使いそうなサービスのポートをまとめて指定するときは ~/.ssh/config に次のように書いておくと便利である。 +---[ ~/.ssh/config ]------------------------------------------ |Host remotehost.hogehoge.jp | LocalForward 8021 remotehost.hogehoge.jp:21 | LocalForward 8025 remotehost.hogehoge.jp:25 | LocalForward 8110 remotehost.hogehoge.jp:110 | Compression yes | CompressionLevel 9 +-------------------------------------------------------------- この例ではftp-control(21番)、SMTP(25番)、POP3(110番)を同時に Port Forwarding することになる。また、Compressionを有効化してい るのでフォワードされたポートの通信にも圧縮が効く。なお、この例の ほかにも ~/.ssh/config に書ける項目はたくさんあるので、それらに ついては man ssh を参照して欲しい。 【Windowsの場合】 寺西高氏による高性能な端末エミュレータ TeraTermPRO[*6] に、ssh プロトコルでの通信を追加するアドオンソフト ttssh 1.5[*7] を組み 込むとWindowsからもsshによるログインが可能となる。ここまでの設定 はドキュメントも豊富なので割愛し、ここでは Port Forwarding の設 定方法について説明する。 まず、ttssh.exeによりログイン先ホスト(remotehostとする)にsshプロ トコルでログインする。そしてTeraTermPROのウィンドウメニューで [Setup] → [SSH Forwarding] を選択するとForwarding Setupウィンド ウが出て来るので、新しい Forwarding を追加するために、[Add]ボタ ンをクリックする。すると Port Forwarding 設定ウィンドウが現れる ので、追加したいポートを記入してから[OK]をクリックする(図4参照)。 Windowsの場合は1024未満のポートの利用も自由にできてしまうので、 リモートのサーバのポート番号をlocalhostのポート番号と合わせてし まったほうが、クライアントソフトウェアの設定が面倒がなくて良いで あろう(次節参照)。 ★図4 「ttsshの Port Forwarding 設定ウィンドウ」 portforward.gif ★脚注*6,7------------------------------------------------------- http://www.vector.co.jp/authors/VA002416/ http://www.zip.com.au/~roca/ttssh.html ----------------------------------------------------------------- 必要な Port Forwarding を設定したら、[Setup] → [Save setup] と メニューを選択することで、設定を保存することができるので次回以降 のログイン時にも有効化することができる。 ・Port Forwardingされたサービスの利用 Port Forwarding の利用が効果的であると考えられるプロトコル、ftp, POP3について、代表的なクライアントプログラムから利用する方法につ いて解説する。以後の例では、 『UNIXの場合 ftp は localhost:8021に、POP3は localhost:8110 にフォ ワードされていて、Windowsの場合 ftp は localhost:21 に、POP3は localhost:110 にフォワードされている』 ものとする。なお、ftpに関しては、Port Forwarding により暗号化さ れるのはコントロールポート(21番)のみであり、データポートは暗号化 されないことに注意されたい。もし、転送するデータの中身の秘密まで も守りたいときにはftpではなく、scpやrsync などのツールを利用する。 また、ここでは Port Forwarding 利用に必要な最低限の設定項目の説 明にとどめている。当然ながら、より詳しい情報を各ソフトウェアのマ ニュアルから得て、正確に設定して欲しい。 【UNIXの場合】 (1)ftp FereBSD標準のftpコマンドの場合は、passive mode での接続を指定す る -p オプションと、ポート番号8021を明示的に指定して、 % ftp -p localhost 8021 とすれば良いので特に難しい点はなかろう。とても便利で利用者が多い と思われるncftp 2.x は少し注意が必要である。もし、localhostへの ftpログインをそれ以前にしたことがなければ、 % ncftp -u -p 8021 localhost とするだけでremotehostにftpログインできる可能性が高い。「可能性 が…」と書いたのは、ncftpの場合一度繋いだホストへの接続条件を設 定ファイルに自動保存してしまうので過去にlocalhostに passive mode 以外で繋げた場合そのmodeを記憶してしまう。一見 localhost:8021 へ のftpログインができたように見えても、ls コマンドがうまく機能しな い場合は、passive mode が有効になっていない可能性があるのでその ような場合は、 % ncftp ncftp> open (過去に接続したホスト一覧が出るのでlocalhostにカーソルを合わせる) ncftp> /ed とすると接続時の条件を変更する画面が出てくるので、 Can user passive FTP: Yes となるようにする。これで次に localhost:8021 に接続したときには passive mode での接続となりデータ転送も有効になる。 Emacsから別ホスト上のファイルの編集をftp越しに行なえる ange-ftp も簡単に Port Forwarding を利用できる。ange-ftp.el で定義されて いるEmacs-Lisp 変数 ange-ftp-ftp-program-args の値に "-p" を追加 したものを ~/.emacs などで定義しておく。Emacs20付属の ange-ftp.el を使うのであれば、 +--[ ~/.emacs ]------------------------------------------------- |(setq ange-ftp-ftp-program-args '("-p" "-i" "-n" "-g" "-v")) +--------------------------------------------------------------- のようなるであろう。この設定をしておき、find-file のときに +--------------------------------------------------------------- | Find file: /localhost 8021:~/hoge.txt +--------------------------------------------------------------- のようにホスト名として "localhost 8021" を指定する。初回接続時に はSPCを打つと補完と見なされてしまうので、SPC自身は C-q SPC か M-SPC で入力する。 (2)POP3 Mew(IM)とfetchmailを例に説明する。 まず、Mewの場合は ~/.im/Config ファイルで +--[ ~/.im/Config ]--------------------------------------------- |Imget.Src=pop/POP@localhost/8110 +--------------------------------------------------------------- のようにホスト名とポート番号を / で区切って指定すれば良い。 fetchmailの場合はそのものズバリの例が man fetchmail に書いてある のでそれを参考にし、~/.fetchmailrc にたとえば次のように書く。 +--[ ~/.fetchmailrc ]------------------------------------------- |poll remotehost.hogehoge.jp with protocol pop3: | via localhost port 8110 +--------------------------------------------------------------- さらに fetchmail の場合は、POP接続直前に起動すべきコマンドを指定 できるので、あらかじめsshでログインしておくという手順も省くこと ができる。そのようにしたい場合は、次のようなエントリにしておく。 +--[ ~/.fetchmailrc ]------------------------------------------- |poll remotehost.hogehoge.jp with protocol pop3: | via localhost port 8110 | preconnect "ssh -f -C -L 8110:remotehost.hogehoge.jp:110 \ | sleep 5 /dev/null"; +--------------------------------------------------------------- 誌面の都合上 \ で折り返して表記したが実際は一行で書く。 【Windowsの場合】 あらかじめ、必要なポートの Forwarding 設定をしてあるttsshでサー バにログインしておき、各クライアントプログラムを利用する。 (1)ftp Passive mode の利用できるftpクライアントならどれでも[*8]利用できる。 例としてWsFTP(LE)の接続方法について解説しよう。WsFTPを起動すると 接続ホスト等を選択・記入するウィンドウが現れるので、接続先ホスト として localhost を記入する。さらに、"Advanced" の設定画面で Passive transfers をチェックする(図5参照)。あとは普通の接続と同 様の手順を行なえば良い。他にも FTP Explorer など、Passive mode が設定できるので Port Forwarding との組合せが利用できる。 ★脚注*8--------------------------------------------------------- Windows 9x 標準のftpコマンドは Passive mode には対応していな いので当然これは利用できない。 ----------------------------------------------------------------- ★図5 「WsFTPの Advanced 設定画面」 wsftp.gif (2)POP3 こちらは特別な設定は不要で、MUAの設定画面のPOPサーバを記述すると ころに、本来のPOPサーバ名ではなく localhost を記入しておけば良い。 ・サーバとなるホストの /etc/hosts.allow の確認 ここまで紹介した使用例に関してサーバとなる接続先ホストで無条件に ftpやPOP3を受け付けていたのでは意味がない。当該サービスポートへ の外部からの直接アクセスは遮断し、Port Forwarding したもののみを 受け付けるようにしておかなければならない。たとえばサーバである remotehost のIPアドレスを仮に 10.0.10.2 だとし、ftp, POP3サービ ス・デーモン・プログラムがそれぞれ ftpd, ipop3d だとすると ftpd ipop3d : 10.0.10.2 localhost : ALLOW ftpd ipop3d : ALL : DENY のような hosts.allow エントリを作れば良い。念のため付け加えてお くが、ssh -L によって、ログイン先のサーバ(10.0.10.2)で、フォワー ドするためのコネクションとして 10.0.10.2 から 10.0.10.2 へのアク セスが発生するので、これを許可するために hosts.allow にもこのア ドレスを書く必要がある。また、FreeBSDなどでは自分自身のIPアドレ スとの通信は、loopback interface (lo0)で処理されるので平文テキス トが外に漏れるのでは、との心配は無用である。利用しているOSの自IP アドレスとの通信にどのインタフェースを用いているかは netstat コ マンドなどで知ることができる。 +--------------------------------------------------------------- |% netstat -nr |Routing tables | 〜中略〜 |Destination Gateway Flags Refs Use Netif Expire |10.0.10.2 xx:xx:xx:xx:xx:xx UHLW 3 60 lo0 | ~~~ +--------------------------------------------------------------- ■●・
yuuji@ Fingerprint16 = FF F9 FF CC E0 FE 5C F7 19 97 28 24 EC 5D 39 BA