Solaris Trusted Extensions 開発ガイド

第 8 章 信頼できる Web ガードプロトタイプ

この章では、Web ガードと呼ばれる安全な Web ブラウジングプロトタイプの構成について説明します。Web ガードは、Web サーバーとその Web コンテンツを隔離するように構成して、インターネットからの攻撃を防止します。

この章で説明する Web ガードプロトタイプは、完全なソリューションではありません。これは、マルチレベルポートがラベルの境界をまたがるプロキシ URL 要求のためにどのように使用できるかを示すプロトタイプです。より完全なソリューションにするには、承認、データフィルタリング、監査などを組み込みます。

プロトタイプで主に実装されるのは管理機能です。プロトタイプは、マルチレベルポート、トラステッドネットワーク、および Apache Web サーバー構成を使用して Web ガードを設定します。管理を目的にする例のほかに、プログラム上の方法を使用して安全な Web ブラウジングプロトタイプを設定できます。

この章の内容は次のとおりです。

管理のための Web ガードプロトタイプ

この節では、Web サーバーとその Web コンテンツを隔離するように構成して、インターネットからの攻撃を防止する安全な Web ブラウジングプロトタイプの例を示します。この Web ガードプロトタイプは、管理上のトラステッドネットワーク機能を使用して 2 段階のフィルタを構成することによって、保護されている Web サーバーと Web コンテンツへのアクセスを制限します。このプロトタイプは、管理上の方法のみによって実装されています。プログラミングの必要はありません。

次の図は、マルチレベル環境の Web ガードプロトタイプの構成を示します。ラベルが図でどのように配置されるかによって、ラベル関係が示されます。縦の関係はラベルの上下を表し、横の関係は分離ラベルを表します。

図 8–1 Web ガードの構成

Web ガードの構成を示す図。

Web 要求は、public ゾーンで構成されている Web サーバーに入り、restricted ゾーンで構成されている Web サーバーに渡されます。

restricted ゾーンは、マルチレベルポート (MLP) を使用して public ゾーンのポート8080 で要求を待機します。この Web サーバーは要求を webservice のラベル付けされたゾーンに渡します。

webservice ゾーンは、MLP を使用して restricted ゾーンのポート 80 で要求を待機し、webcontent のラベル付けされたゾーンからコンテンツを読み取ります。

webcontent ゾーンは動作可能状態にあって、その Web コンテンツを /export/home ファイルシステムに格納しています。このファイルシステムは、その他のすべてのラベル付けされたゾーンに自動的にマウントされます。ゾーンが動作可能状態である場合、そのゾーンで実行されているプロセスはありません。すなわち、基本的にゾーンは、webservice ゾーンに直接接続されたディスクドライブです。

    Web ガードプロトタイプを構成するには、次のハイレベルタスクを実行します。

  1. 安全な Web ブラウジング環境にラベルを構成するための label_encodings ファイルの変更

    デフォルトの label_encodings ファイルを更新して、2 つの新しいラベル (WEB GUARD SERVICE および WEB GUARD CONTENT) を構成します。label_encodings ファイルの変更」を参照してください。

  2. トラステッドネットワークの構成

    restricted および webservice のラベル付けされたゾーンに、プライベート IP アドレスおよび MLP を構成します。「トラステッドネットワークの構成」を参照してください。

  3. Apache Web サーバーの構成

    publicrestricted、および webservice ゾーンは、すべて Web サーバーを構成します。この例で使用される Web サーバーは Apache です。「Apache Web サーバーの構成」を参照してください。

label_encodings ファイルの変更

デフォルトの label_encodings ファイルを更新して、2 つの新しいラベル (WEB GUARD SERVICE および WEB GUARD CONTENT) を構成します。デフォルトファイルの一部である SANDBOX ラベルは、WEB GUARD CONTENT ラベルとなるように変更します。WEB GUARD SERVICE ラベルを追加します。

label_encodings ファイルを /etc/security/tsol ディレクトリにインストールする必要があります。このファイルは、既存の Trusted Extensions インストールに追加してインストールできます。

更新したファイルを /etc/security/tsol ディレクトリにインストールしたら、次のようにして、新しい label_encodings ファイルをアクティブにします。


# svcadm restart svc:/system/labeld

この Web ガードプロトタイプで使用される label_encodings ファイルは、次のとおりです。

* ident	"@(#)label_encodings.simple	5.15	05/08/09 SMI"
*
* Copyright 2005 Sun Microsystems, Inc.  All rights reserved.
* 使用はライセンス条項に従ってください。
*
* この例は、電子メールおよびプリンタ出力のラベル付けに関して、
* 実際のサイトの法的な情報保護要件を満たすラベルを指定する方法を 
* 示します。ここに示すラベルは、ファイルおよびディレクトリに対する
* ユーザー認可上限ラベルおよび機密ラベルに基づく必須アクセス制御 
* チェックを強制するためにも使用できます。  

VERSION= Sun Microsystems, Inc. Example Version - 6.0. 2/15/05

CLASSIFICATIONS:

name= PUBLIC; sname= PUB; value= 2; initial compartments= 4;
name= CONFIDENTIAL; sname= CNF; value= 4; initial compartments= 4;
name= WEB GUARD; sname= WEB; value= 5; initial compartments= 0;
name= MAX LABEL; sname= MAX; value= 10; initial compartments= 0 4 5;

INFORMATION LABELS:

WORDS:

name= :; prefix;

name= INTERNAL USE ONLY; sname= INTERNAL; compartments= 1 ~2; minclass= CNF; 
name= NEED TO KNOW; sname= NEED TO KNOW; compartments= 1-2 ~3; minclass= CNF; 
name= RESTRICTED; compartments= 1-3; minclass= CNF; 
name= CONTENT; compartments= 0 ~1 ~2 ~3; minclass= WEB; 
name= SERVICE; compartments= 5; minclass= WEB; 

REQUIRED COMBINATIONS:

COMBINATION CONSTRAINTS:

SENSITIVITY LABELS:

WORDS:

name= :; prefix;

name= INTERNAL USE ONLY; sname= INTERNAL; compartments= 1 ~2; minclass= CNF;
prefix= :

name= NEED TO KNOW; sname= NEED TO KNOW; compartments= 1-2 ~3; minclass= CNF;
prefix= :

name= RESTRICTED; compartments= 1-3; minclass= CNF; prefix= :

name= CONTENT; compartments= 0 ~1 ~2 ~3; minclass= WEB;

name= SERVICE; compartments= 5; minclass= WEB;

REQUIRED COMBINATIONS:

COMBINATION CONSTRAINTS:

CLEARANCES:

WORDS:

name= INTERNAL USE ONLY; sname= INTERNAL; compartments= 1 ~2; minclass= CNF;
name= NEED TO KNOW; sname= NEED TO KNOW; compartments= 1-2 ~3; minclass= CNF;
name= RESTRICTED; sname= RESTRICTED; compartments= 1-3; minclass= CNF;
name= CONTENT; compartments= 0 ~1 ~2 ~3; minclass= WEB; 
name= SERVICE; compartments= 5; minclass= WEB;

REQUIRED COMBINATIONS:

COMBINATION CONSTRAINTS:

CHANNELS:

WORDS:

PRINTER BANNERS:

WORDS:

ACCREDITATION RANGE:

classification= PUB; all compartment combinations valid;
classification= WEB; all compartment combinations valid;
classification= CNF; all compartment combinations valid except: CNF

minimum clearance= PUB;
minimum sensitivity label= PUB;
minimum protect as classification= PUB;

* ローカルサイト定義とローカルで構成可能なオプション。

LOCAL DEFINITIONS:

default flags= 0x0;
forced flags= 0x0;
 
Default Label View is Internal;
 
Classification Name= Classification;
Compartments Name= Sensitivity;

Default User Sensitivity Label= PUB;
Default User Clearance= CNF NEED TO KNOW;
 
COLOR NAMES:

    label= Admin_Low;           color= #bdbdbd;

    label= PUB;                 color= blue violet;
    label= WEB SERVICE;         color= yellow;
    label= CNF;                 color= navy blue;
    label= CNF : INTERNAL USE ONLY;  color= blue;
    label= CNF : NEED TO KNOW;  color= #00bfff;
    label= CNF : RESTRICTED;    color= #87ceff;
 
    label= Admin_High;          color= #636363;
 
* ローカルサイト定義の終わり

label_encodings ファイルについての詳細は、『Solaris Trusted Extensions ラベルの管理』を参照してください。

トラステッドネットワークの構成

restricted および webservice ゾーンには、すでに共有している IP アドレスのほかに、プライベート IP アドレスを割り当てます。各プライベート IP アドレスはマルチレベルポートを構成し、制限されたラベルセットに関連付けられます。

次の表は、それぞれのラベル付けされたゾーンのネットワーク構成を示します。

ゾーン名 

ゾーンラベル 

ローカル IP アドレス 

ホスト名 

マルチレベルポート 

セキュリティーラベルセット 

restricted

CONFIDENTIAL :RESTRICTED

10.4.5.6

proxy

8080/tcp

PUBLIC

webservice

WEB GUARD SERVICE

10.1.2.3

webservice

80/tcp

CONFIDENTIAL :RESTRICTED

webcontent

WEB GUARD CONTENT

なし 

 

 

 

最初に、新しいゾーンを作成します。public ゾーンなどの既存のゾーンを複製できます。これらのゾーンを作成したら、zonecfg コマンドを使用して、表に示したアドレスのネットワークおよびローカルインタフェース名を追加します。

たとえば、次のコマンドは、10.4.5.6 の IP アドレスおよび bge0 インタフェースを restricted ゾーンに関連付けます。


# zonecfg -z restricted
add net
set address=10.4.5.6
set physical=bge0
end
exit

それぞれのラベル付けされたゾーンに IP アドレスおよびネットワークインタフェースを指定したら、Solaris 管理コンソールを使用して表の残りの値を設定します。このツールを使用する場合、必ず Scope=Files および Policy=TSOL のツールボックスを選択してください。

    次の手順に従ってゾーン構成を終了します。

  1. スーパーユーザーとして Solaris 管理コンソールを起動します。


    # &
    
  2. 「ナビゲーション」パネルから「このコンピュータ」を選択し、「システム構成」をクリックします。

  3. 「コンピュータおよびネットワーク」アイコンをクリックします。

  4. 「コンピュータ」アイコンをクリックし、「アクションからコンピュータを追加」メニューを選択します。

  5. proxy ホストおよび webservice ホストのホスト名および IP アドレスを追加します。

  6. 「ナビゲーション」パネルから「信頼できるネットワークゾーン」を選択します。

    列を拡張する必要のある場合があります。ゾーン名がリストに表示されない場合、「アクション」メニューから「ゾーン構成を追加」を選択します。

  7. 各ゾーンにラベルを割り当て、「ローカル IP アドレスの MLP 構成」フィールドに適切なポートおよびプロトコルを指定します。

  8. 「ナビゲーション」パネルから「セキュリティーファミリ」アイコンをクリックし、「アクション」メニューから「テンプレートを追加」を選択します。

    表の情報に基づいて proxy ホスト名および webservices ホスト名のテンプレートを追加します。

    1. テンプレート名の該当するホスト名を指定します。

    2. 「ホストタイプ」フィールドで CIPSO を指定します。

    3. 「最下位ラベル」および「最上位ラベル」フィールドで該当するゾーンラベルを指定します。

    4. 「セキュリティーラベルセット」フィールドで該当するセキュリティーラベルを指定します。

    5. 「明示的に割り当てられたホスト」タブをクリックします。

    6. 「エントリを追加」セクションで、 該当するローカル IP アドレスを各テンプレートに追加します。

  9. Solaris 管理コンソールを終了します。

Solaris 管理コンソールを終了したら、影響があるゾーンを起動または再起動します。大域ゾーンで、新しいアドレスのルートを追加します。shared-IP-addr は共有 IP アドレスです。


# route add proxy shared-IP-addr
# route add webservice shared-IP-addr

Apache Web サーバーの構成

Apache Web サーバーのインスタンスは、public ゾーン、restricted ゾーン、および webservice ゾーンで実行されます。各ゾーンで、次のように /etc/apache/httpd.conf ファイルを変更します。

ラベル付けされたゾーンごとに Apache Web サーバーの構成を更新したら、webcontent ゾーンの /export/home/www/htdocs ディレクトリに Web コンテンツを格納します。

/export/home/www/htdocs ディレクトリに demo ディレクトリを作成し、そのディレクトリにテストで使用する index.html ファイルを作成します。

起動時に、webservice ゾーンに lofs を使用することによって、/export/home ディレクトリは自動的にマウントされます。webcontent ゾーンは動作可能状態にする必要があるだけです。


# zoneadm -z webcontent ready

ゾーンが動作可能状態である場合、そのゾーンで実行されているプロセスはありません。ゾーンのファイルシステムは、webservice ゾーンによって読み取り専用でマウントできます。このように Web コンテンツにアクセスすると、コンテンツが変更されることがありません。

信頼できる Web ガードデモの実行

public ゾーンのブラウザから、または PUBLIC ラベルで実行されている遠隔ブラウザから、次の URL を入力します。


http://server-name/demo

webcontent ゾーンのデフォルトの index.html ファイルがブラウザに表示されます。

Web ガードフローはバイパスできません。webservice ゾーンの Web サーバーは、public ゾーンおよび遠隔ホストからパケットを受信できません。webcontent ゾーンが動作可能状態であるので、この Web コンテンツは変更できません。

下位レベルの信頼できないサーバーへのアクセス

場合によって、クライアントは、ラベル付けされていないシステムのサーバーにアクセスできなければなりません。「ラベル付けされていないシステム」は、Trusted Extensions ソフトウェアを実行しないシステムです。この場合、マルチレベルポートは、大域ゾーンまたはラベル付けされたゾーンで実行される特権サーバーに制限されるので使用できません。

たとえば、ブラウザが INTERNAL ゾーンで実行されているとします。tnrhdb データベースによって PUBLIC 機密ラベルが割り当てられた単一レベルネットワークで実行されている Web サーバーにアクセスしてみます。デフォルトでは、このようなアクセスは許可されません。それに対し、HTTP 要求を PUBLIC の Web サーバーに転送する特権プロキシーサーバーを記述できます。プロキシは、SO_MAC_EXEMPT と呼ばれる特別な Trusted Extensions ソケットオプションを使用します。このソケットオプションによって、信頼できない下位レベルのサービスに要求が送信され、サービスからの応答が要求元に返されます。


注 –

SO_MAC_EXEMPT オプションを使用する場合、保護されないダウングレードチャネルになるので、十分に注意が必要です。呼び出し元プロセスの実効セットに PRIV_NET_MAC_EXEMPT 特権がない場合は、SO_MAC_EXEMPT オプションを設定できません。このようなプロセスでは、高位レベルのデータが低位レベルのサービスに漏れないように、その自身のデータフィルタリングポリシーを強制する必要があります。たとえば、単語が値として使用されないように、URL の不適切な箇所をプロキシで削除します。


次のコード抜粋は、connect.c にある wget コマンドの connect_to_ip() ルーチンの変更バージョンにおけるSO_MAC_EXEMPT の使用方法を示します。SO_MAC_EXEMPT オプションの設定方法を明らかにするために、setsockopt() の呼び出しが追加されています。

int
connect_to_ip (const ip_address *ip, int port, const char *print)
{
  struct sockaddr_storage ss;
  struct sockaddr *sa = (struct sockaddr *)&ss;
  int sock;
  int on = 1;

  /* PRINT が NULL 以外の場合、PRINT は接続先のホスト名で
 "Connecting to..." 行を出力する。 */
  if (print)
    {
      const char *txt_addr = pretty_print_address (ip);
      if (print && 0 != strcmp (print, txt_addr))
	logprintf (LOG_VERBOSE, _("Connecting to %s|%s|:%d... "),
		   escnonprint (print), txt_addr, port);
      else
	logprintf (LOG_VERBOSE, _("Connecting to %s:%d... "), txt_addr, port);
    }

  /* sockaddr 情報を SA に格納する。 */
  sockaddr_set_data (sa, ip, port);

  /* アドレスに対応するファミリのソケットを作成する。  */
  sock = socket (sa->sa_family, SOCK_STREAM, 0);
  if (sock < 0)
    goto err;

  if (setsockopt (sock, SOL_SOCKET, SO_MAC_EXEMPT, &on, sizeof (on)) == -1) {
    perror("setsockopt SO_MAC_EXEMPT");
  }

#if defined(ENABLE_IPV6) && defined(IPV6_V6ONLY)
  if (opt.ipv6_only) {
    /* エラーの場合、そのまま実行する... */
    int err = setsockopt (sock, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof (on));
  }
#endif