HOMELinux道場Linux道場ネットワーク編第6回 TCPWrappers(hosts.allow,hosts.deny)とSSHの公開鍵認証について

Linux道場ネットワーク編

第6回TCPWrappers(hosts.allow,hosts.deny)とSSHの公開鍵認証について

はじめに

今回は、セキュリティの向上として、TCPWrappers(hosts.allow,hosts.deny)とSSHの公開鍵認証について取り上げます。

「TCPWrappers」について

「TCPWrappers」はネットワークを利用した接続の許可・許否を判断し、接続制御(制限)を行います。
「TCPWrappers」(デーモン名:tcpd)は、サーバープログラム(inetd)と連携して動作し、サーバープログラム (inet(telnetd/ftpdなどの/etc/inetd.confに記述されているサービス))の代わりに、接続要求を受け取り、「hosts.allow」と「hosts.deny」の二つのファイルを参照して、接続可否の判断を行います。
接続を許可した場合は、それぞれのサーバープログラムに処理を引き渡します。

「hosts.allow」と「hosts.deny」について

接続可否を判断する「hosts.allow」と「hosts.deny」の二つのファイルは(基本的に)/etcディレクトリの直下に在ります。
「hosts.allow」は接続を許可するホスト(サービス)を、「hosts.deny」は接続を許可しないホスト(サービス)を記述します。
「hosts.allow」、「hosts.deny」の書式は共に、「許可(許否)するサービス名:許可(許否)するホスト」です。

  • ※「サービス名:ホスト」以降に「:」を挟みオプション(コメント)を記述できます。
    図1は「hosts.allow」、図2は「hosts.deny」の設定例です。
  • 図1.hosts.allow 設定例図1.hosts.allow 設定例
  • 図2.hosts.deny設定例図2.hosts.deny設定例

表1図1.「hosts.allow」、図2.「hosts.deny」の設定例の意味です。

表1.hosts.allow ,hosts.denyの設定例の意味表1.hosts.allow ,hosts.denyの設定例の意味

図中(表中)の設定にある「ALL」は、全てのサービス/またはホストを意味します。
サービス名は/etc/inetd.confで有効にしている(inetd経由で接続するサービス(telnetであれば「in.telnetd」※図3 参照)を記述します。(※inetd経由で起動されるサービスには、サービス名の前に「in.」がつく場合があります。(telnetd → in.telnetd))

図3./etc/inetd.conf設定ファイル図3./etc/inetd.conf設定ファイル

「tcpdchk」コマンドと「tcpdmatch」コマンドについて

「hosts.allow」と「hosts.deny」の構文確認は「tcpdchk」コマンドで行うことができます。
図4図1,図2の設定で「tcpdchk」コマンドを実行したときの例です。構文にエラーが無い場合は何も表示されません。
「-v」オプションをつけて実行すると設定した制御規則情報を表示します。

図4. 「tcpdchk」,「tcpdchk -v」実行例図4. 「tcpdchk」,「tcpdchk -v」実行例

表示項目にある「access」の「granted」は接続許可を、「denied」は接続許否を意味します。
「tcpdmatch」コマンドでは、接続条件を指定した確認が行えます。書式は「tcpdmatch サービス名 ホスト」です。
図5図1,図2の設定で、サービスに「in.telnetd」、ホスト名に「xxx.xxx.xxx.xxx」(接続を許可するIPアドレス)と「yyy.yyy.yyy.yyy」(接続を許可しないIPアドレス)を指定して実行した時の例です。

図5. 「tcpdmatch」実行例図5. 「tcpdmatch」実行例

「tcpd」(「hosts.allow」と「hosts.deny」)の照合について

「tcpd」は「hosts.allow」、「hosts.deny」の順に接続可否の判断を行います。他のホストからの接続要求を受け取ると「tcpd」は、「hosts.allow」に接続元のホスト情報が記述されているかを確認します。記述されている場合は接続を許可し、記述が無い場合は「hosts.deny」に記述されているか確認します。「hosts.deny」にも記述されていない場合は接続を許可し、記述されている場合は接続を拒否します。図6は「tcpd」の照合の流れのフロー図です。

図6.tcpd処理フロー図6.tcpd処理フロー

「tcpd」の照合では「hosts.allow」に接続元のホスト情報が記述されていると「hosts.deny」の評価は行われません。
「hosts.allow」と「hosts.deny」の両方に記述が無い場合は接続を許可します。一般的に「hosts.deny」には「ALL:ALL」(全てのホストからの接続を全てのサービスで拒否)を記述し、「hosts.allow」に接続を許可する「サービス名:ホスト」を記述して使用します。
IPアドレスを「192.168.0.25」に設定したクライアント(接続元)とサーバー「ホスト名:lpic」(接続先)を使用して、実際に「tcpd」の動きを確認してみます。わかりやすくする為、全てのホストから接続を全てのサービスで拒否する設定にします。
(サーバーの「hosts.allow」には何も記述せず、「hosts.deny」には「ALL:ALL」を記述)
このように設定した環境でクライアントからサーバーにtelnetを使用して接続を試みます。(※図7参照)

図7.「tcpd」検証環境図7.「tcpd」検証環境

図8はクライアントから接続要求を受けたときのサーバー(ホスト名lpic)のプロセス稼働状況(topコマンド実行)画面です。
図中の赤枠に「tcpd」のプロセスが動作していることが確認できます。

図8. サーバー(ホスト名lpic)のプロセス稼働状況(topコマンド実行)画面図8. サーバー(ホスト名lpic)のプロセス稼働状況(topコマンド実行)画面

全てのホストから接続を全てのサービスで拒否する設定にしているので、当然クライアントからの接続は行えません。
サーバーのログには、接続要求を拒否したログが出力されます。(※図9参照)

図9.tcpdの接続許否時のログ図9.tcpdの接続許否時のログ

  • ※「TCPWrappers」ログの出力先はディストリビューションやsyslog.confの設定により異なります。認証関連のログは基本的に/var/log/secureに出力されます。
    図10は「hosts.allow」に「in.telnetd:192.168.0.25 :allow」を追記し、「192.168.0.25」のホストから「telnet」によるログインを許可した時のログです。

図10.tcpdの接続許可時のログ図10.tcpdの接続許可時のログ

このように、「TCPWrappers」(tcpd)は、接続要求の度に、接続可否の判断を行います。
Linux OSインストール直後の「hosts.allow」、「hosts.deny」ファイルにはコメントアウトされた説明文(設定例)以外に何も記述されていませんので注意が必要です。この状態だと全てのホストから全てのサービスでの接続を許可してしまいます。
特に外部に公開するサーバーについては、「hosts.deny」への「ALL:ALL」の記述を忘れずに行いましょう。
また、「hosts.allow」「hosts.deny」への特殊な記述として「ALL:PARANOID」の記述を行うと、ホスト名からDNS検索したアドレスとサービス要求元のアドレスが一致するか確認を行います。一致しない場合は接続を許可しません。(ホスト名/ドメイン名の偽造による接続を防ぎます。)図11は「hosts.allow」に「ALL:PARANOID」を記述したサーバーに対してホスト名「Imitation.Imitation.com」:IPアドレス「yyy.yyy.yyy.yyy」(ホスト名/IPアドレスを偽造した状態)が、接続要求を行ったときにサーバーがホスト名とIPアドレスの不一致を検知して出力したときのログです。

図11.「PARANOID」を記述したときのログ図11.「PARANOID」を記述したときのログ

  • ※「sshd」はinetd経由で接続を行いませんが、TCPWrappersによる制限が行えます。

このように「TCPWrappers」(tcpd,hosts.allw,hosts.deny)を使用すると外部から不正に接続される可能性を下げることができます。

SSHでの公開鍵認証について

SSHでの公開鍵認証について、初めに公開鍵認証で使われる公開鍵暗号方式、次に公開鍵認証を行う為に必要な「公開鍵」と「秘密鍵」を作成する「ssh-keygen」コマンドと作成した公開鍵のサーバーへの登録について説明します。

公開鍵暗号方式について

公開鍵暗号方式とは暗号方式の一つでデータの暗号化を行うための鍵と復号化を行う為の鍵を分ける暗号方式です。
データの暗号化を行う鍵を「公開鍵」、復号化を行う鍵を「秘密鍵」といいます。各鍵は名称通り、公開鍵は外部に公開し、秘密鍵は秘密(公開しないよう)にします。公開鍵暗号方式でデータの送信を行う場合、送信元は受信先が公開している公開鍵で送信するデータの暗号化を行い、受信先は暗号化されたデータを秘密鍵で復号化します。
データの復号化は公開鍵と対になる秘密鍵でしか行えないので、仮に第三者が暗号化したデータを取得したとしても(秘密鍵が漏洩している等の特殊な場合を除き)復号化を行うことはできません。(※図12参照)

図12.公開鍵暗号方式による通信図12.公開鍵暗号方式による通信

クライアント・サーバー間で公開鍵認証を使用したSSHについて

公開鍵認証を使用したSSHでは、クライアントがサーバーに対して接続要求を行うと、サーバーはクライアントに対してクライアントの公開鍵で暗号化したメッセージを送信します。クライアントは自身の秘密鍵で暗号化されたメッセージの復号化を行い、サーバーに返信します。サーバーは暗号化する前のメッセージと復号化されたメッセージを比較し、一致すれば接続要求元は正しいクライアントであると判断し、接続を許可します。公開鍵認証では、ログイン時にユーザー名とパスワードを送信する必要がなくなること、ユーザー名とパスワードを利用した「なりすまし」(不正に入手したユーザー名、パスワードでログインする)の可能性を減らすことができることから、セキュリティが向上します。(※図13参照)

図13.クライアント-サーバー間での公開鍵認証図13.クライアント-サーバー間での公開鍵認証

「ssh-keygen」コマンドについて

公開鍵と秘密鍵の作成には、「ssh-keygen」コマンドを実行します。「-t」オプションをつけると暗号化の種類を選択して作成することができます。暗号化の種類には「rsa1」、「rsa」、「dsa」があり、それぞれ暗号方式と対応するSSHのバージョンが異なります。
表2は暗号化の種類と対応するSSHのバージョン、作成される鍵の名称の一覧です。

表2.暗号化の種類と対応するSSHのバージョン表2.暗号化の種類と対応するSSHのバージョン

SSHでの公開鍵認証を行うまでの設定について

実際にクライアント(ホスト名:info,ユーザー名:lpic)とサーバー(ホスト名:fifo:ユーザー名:lpic)の2台のLinux OS PCを使って、公開鍵と秘密鍵の作成とSSHでの公開鍵認証を行うまでの手順を説明します。
2台のLinux OSにはSSH(OpenSSH,OpenSSL)モジュールが導入されていることを前提とします。

公開鍵と秘密鍵の作成

初めにクライアントで公開鍵と秘密鍵の作成を行います。クライアントに鍵を作成するユーザー(実施する環境ではlpic)でログインします。今回は暗号化の種類に「dsa」を指定して鍵の作成を行います。「ssh-keygen」に「-t dsa」 オプションを追加してコマンドを実行します。(※図14参照)

図14.ssh-keygen実行画面図14.ssh-keygen実行画面

コマンド実行後、「Enter file in which to save the key (/home/lpic/.ssh/id_dsa):」(作成する鍵ファイルの保存場所/名前)についての入力を求められます。(鍵の作成が行われる保存ディレクトリのデフォルトは「~./ssh」になります。また鍵ファイルの名称は暗号化の種類によって異なります。表2参照))基本的に変更を行う必要がないので、そのまま「Enter」キーを押します。
次に「Enter passphrase (empty for no passphrase):」(鍵を使う為のパスフレーズ)について入力を求められます。
パスフレーズの入力を行うと、「Enter same passphrase again:」(パスフレーズの再入力)が求められるので、パスフレーズの再入力を行います。入力が完了すると「~/.ssh」ディレクトリ内に鍵ファイルが作成されます。(※図15参照)

図15.クライアントの「~/.ssh」ディレクトリの中身図15.クライアントの「~/.ssh」ディレクトリの中身

公開鍵のサーバーへの登録

クライアントで作成した公開鍵ファイル(id_dsa.pub)を、(FTP/FD等を利用して)サーバーのユーザーディレクトリにコピーします。(※図16参照)

図16.サーバーのユーザーディレクトリにクライアントの公開鍵をコピー図16.サーバーのユーザーディレクトリにクライアントの公開鍵をコピー

サーバーが公開鍵認証を行うファイルは「~/.ssh/authorized_key」ファイルになります。サーバーのユーザーディレクトリ上で「cat id_dsa.pub >> ~/.ssh/authorized_keys」を実行し、クライアントの公開鍵をサーバーの「authorized_key」に登録を行います。(※図17参照)

図17.クライアント公開鍵のサーバーへの登録図17.クライアント公開鍵のサーバーへの登録

次にパーミッションの変更(確認)を行います。「~./ssh」ディレクトリのパーミッションは「rwx- - - - - -」(700)、「~ /.ssh/authorized_keys」ファイルのパーミッションは「rx- - - - - - -」(600)に変更(確認)します。この時点で公開鍵認証が行われるようになります。(※図18参照)

図18.「~/.ssh/authorized_key」ファイルのパーミッション確認図18.「~/.ssh/authorized_key」ファイルのパーミッション確認

但し、この時点では公開鍵の登録を行ったユーザーのみ公開鍵認証によるログインが行われるだけなので、サーバーに対して、ユーザー名とパスワードによるログインを許可しないように、「/etc/ssh/sshd_config」に記述されている「PasswordAuthentication」(パスワード認証)の設定を「yes」から「no」に変更します。(※図19参照) (※デフォルトでは「PasswordAuthentication yes」の状態でコメントアウトされています。) 設定変更後、サーバーのsshを再起動します。

図19.「/etc/ssh/sshd_config」の設定図19.「/etc/ssh/sshd_config」の設定

最後にクライアントからサーバーへの接続を実施し、公開鍵認証が行われるか確認します。
正しく公開鍵の登録、公開鍵認証の設定が行われていると鍵作成時に入力したパスフレーズの入力を求められます。
鍵作成時に入力したパスフレーズの入力を行うとサーバーへのログインが行えます。(※図20参照)

図20.公開鍵認証による接続確認図20.公開鍵認証による接続確認

終わりに

今回はセキュリティの向上として、「TCPWrappers」(hosts.allow/hosts.deny)とSSHの公開鍵認証について取り上げました。次回はDNSの仕組みについて取り上げたいと思います。

マイクロテクノロジー株式会社

コラム執筆/森谷 仁
マイクロテクノロジー株式会社 管理本部 情報システム室

〒101-0021
東京都千代田区外神田5-1-2末広ビル
TEL 03-3833-8080

このページのトップへ