SELinuxのセキュリティポリシーを確認する

2018年3月9日(金)
能登 上総

はじめに

前回紹介したSELinuxを有効にすると、セキュリティポリシーに従って各プロセスが必要なファイルやポート等へしかアクセスできなくなり、万一攻撃された場合の被害を最小限にできます。ただし、セキュリティポリシーが適切に設定されていることが大前提となります。Red Hat系のLinuxディストリビューションでは事前にセキュリティポリシーが設定されていますが、利便性を重視し、あえて設定を甘くしてある部分が散在しています。

例えば、2017年3月に発生したApache Struts2の脆弱性では、Tomcatに関連するデフォルトのセキュリティポリシー設定が甘かったため防御できませんでした。(本件の詳細はOSSセキュリティ技術の会のHPに記載しています)。

このようなことから、企業システムではSELinux適用時にセキュリティポリシーがどのように設定されているかを理解した上で利用することが重要になります。そのためには、まずプロセスが乗っ取られた際の影響範囲、つまりプロセスがアクセスできる対象(ファイルやポートなど)を調査する必要がありますが、手作業でやろうとすると複数のコマンドや大量のデータの存在により困難です。

そこで、今回はまず手作業での調査方法を解説しSELinuxの理解を深めていただいた上で、調査作業を簡便化するツールを紹介します。

手作業による調査方法

今回はhttpdプロセスがreadパーミッションを持つ/etc以下のファイルを調査してみます。sesearchやseinfo、semanageなどのツールを使用して、以下の手順で行います。

①httpdプロセスに関連付けられたポリシールールを検索し、プロセスがreadパーミッションを持つタイプとアトリビュートを調査
②得られたアトリビュートに属するタイプを調査
③得られたタイプを設定するファイルコンテキストを調査
④得られたファイルコンテキストのファイルパスパターンと/etc以下のファイルパスとをマッチングし、httpdプロセスがreadパーミッションを持つファイルを調査

なお、アトリビュートとは複数のタイプを1つのグループにまとめたものです。アトリビュートにポリシールールが定義されている場合、その配下にあるタイプ全てにそのルールが適応されることになります。

まず、httpdプロセスに関連付けられたポリシールールを検索し、sesearchコマンドでreadパーミッションを持つタイプとアトリビュートの一覧を取得します。

# sesearch -A --source httpd_t --perm read --class file
Found 276 semantic av rules:
   allow httpd_t proc_net_t : file { ioctl read getattr lock open } ;
   allow httpd_t httpd_cache_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ;
   allow httpd_t cvs_data_t : file { ioctl read getattr lock open } ;
(略)
   allow httpd_t pki_apache_var_run : file { ioctl read getattr lock open } ;
   allow httpd_t httpd_config_t : file { ioctl read getattr lock open } ;
   allow httpd_t var_lib_t : file { ioctl read getattr lock open } ;
(略)
   allow httpd_t base_ro_file_type : file { ioctl read getattr lock execute execute_no_trans open } ;
   allow httpd_t application_exec_type : file { ioctl read getattr lock execute execute_no_trans open } ;
   allow httpd_t shell_exec_t : file { ioctl read getattr lock execute execute_no_trans open } ;
(略)

赤字で示した部分はhttpdプロセスがreadパーミッションを持つタイプまたはアトリビュートです。読み方を簡単に説明すると、以下のようになります。

allow アクセス元ドメイン アクセス先タイプ : ファイル種別 { 許可するパーミッション }

末尾が_tで終わっているものがタイプ、それ以外がアトリビュートです。上記を実行した筆者の環境で集計すると、タイプが223種、アトリビュートが14種表示されました。

アトリビュートはタイプのグループのため、グループ内のタイプを展開する必要があります。展開するにはseinfoコマンドを使用します。以下は、application_exec_typeを展開した例です。

# seinfo --attribute=application_exec_type -x
   application_exec_type
      abrt_exec_t
      abrt_dump_oops_exec_t
      abrt_handle_event_exec_t
      abrt_helper_exec_t
      abrt_retrace_worker_exec_t
      abrt_retrace_coredump_exec_t
      accountsd_exec_t
      acct_exec_t
(略)

赤字で示した部分が展開されたタイプです。これをsesearchコマンドで表示されたアトリビュート全てに実行する必要があります。筆者の環境では14種全てを展開すると813種のタイプが得られました。最初の223種と合わせて重複を省くと、合計930種のタイプを得ることができました。

タイプを抽出したら、次はこれらのタイプがどのファイルに設定されているかを1つ1つ確認していきます。例としてhttpd_config_tについて見てみます。sesearchの結果、httpdプロセスはhttpd_config_tに対してreadパーミッションを持つことが分かりました。続けてsemanageコマンドを使用して、このタイプをファイルに設定するファイルコンテキストを調査します。

# semanage fcontext --list | grep httpd_config_t
/etc/httpd(/.*)?          all files   system_u:object_r:httpd_config_t:s0
/etc/nginx(/.*)?          all files   system_u:object_r:httpd_config_t:s0
(略)

その結果、httpd_config_tをファイルに設定するファイルコンテキストが全部で11個得られました。青字の正規表現で表されるファイルパスパターンにマッチしたファイルにhttpd_config_tが設定されます。本来は全てのファイルパスパターンを確認してマッチするファイルを列挙しますが、ここでは例として/etc/httpd(/.*)? を確認します。

正規表現にマッチするファイルを確認するには、findコマンドとgrepコマンドを組み合わせると簡単です。今回は/etc以下のファイルを調査するので、次のようになります。

# find /etc | grep -E "/etc/httpd(/.*)?"
/etc/httpd
/etc/httpd/conf
/etc/httpd/conf/httpd.conf
/etc/httpd/conf/magic
/etc/httpd/conf.d
(略)

これでhttpdプロセスがreadパーミッションを持つファイルを取得できました。これをすべてのタイプに行う必要があります(今回の例では930種)。さすがに手作業では困難なので、この作業を自動化するツールを紹介します。

「SELinux Type Enforcement Lookup」による調査

「SELinux Type Enforcement Lookup」は、SELinux制御下でプロセスがどのファイルに対してパーミッションを持っているかを調査するためのCUIツールです。こちらのサイトから入手できます。

まず、実際に実行してみましょう。なお、本ツールはPythonで書かれており、動作にはPython2系が必要です。今回はhttpdプロセスが/etc以下のディレクトリでreadパーミッションを持つファイルを調査します。

#python selinux-te-lookup.py httpd_t --root /etc --stdout --perm read --class file
File-Context-Pattern,File-Context-Target-Type,File-Context-Label,Matched-File-Path,File-Type,File-Label,SAME-SELinux-Type
/etc/.*,all files,system_u:object_r:etc_t:s0,/etc/fstab,f,system_u:object_r:etc_t:s0,OK
/etc/.*,all files,system_u:object_r:etc_t:s0,/etc/crypttab,f,system_u:object_r:etc_t:s0,OK
/etc/resolv\.conf.*,all files,system_u:object_r:net_conf_t:s0,/etc/resolv.conf,f,system_u:object_r:net_conf_t:s0,OK
/etc/pki(/.*)?,all files,system_u:object_r:cert_t:s0,/etc/pki/product-default/69.pem,f,system_u:object_r:cert_t:s0,OK
/etc/pki(/.*)?,all files,system_u:object_r:cert_t:s0,/etc/pki/rpm-gpg/RPM-GPG-KEY-redhat-beta,f,system_u:object_r:cert_t:s0,OK /var/www(/.*)?,all files,system_u:object_r:httpd_sys_content_t:s0,/var/www/html,d,system_u:object_r:httpd_sys_content_t:s0,OK
(略)

それでは、実行したコマンドから見ていきましょう。

#python selinux-te-lookup.py httpd_t --root /etc --stdout --perm read --class file

第1引数にhttpd_tが指定されています。これはhttpdプロセスのSELinuxドメインです。第1引数には調査したいプロセスのドメインを指定します。

第2、第3引数では--rootオプションと、その値として/etcディレクトリが指定されています。これはディレクトリの調査範囲を/etc以下に限定する働きがあります。指定しなかった場合はルートディレクトリから探索されます。

第4引数の--stdoutは、結果を標準出力に表示するためのものです。指定しなかった場合はファイルに出力されます。

第5、第6引数では--permオプションと、その値としてreadパーミッションを指定しています。これは、検索対象をプロセスが指定したパーミッションを持つファイルに限定する働きがあります。

第7、第8引数では--classオプションと、その値としてfileを指定しています。これは検索対象のファイル種別(ファイル、ディレクトリなど)を指定しています。

次に、出力を見てみましょう。出力はCSV形式です。まずヘッダーを確認します。

File-Context-Pattern,File-Context-Target-Type,File-Context-Label,Matched-File-Path,File-Type,File-Label,SAME-SELinux-Type

1レコードはファイルの情報と、そのファイルのラベルを設定したファイルコンテキストの情報が表示されています。File-Context-Pattern、File-Context-Target-Type、File-Context-Labelがファイルコンテキストの情報です。それぞれファイルパスのマッチングパターン、マッチするファイル種別(ファイル、ディレクトリなど)、設定するラベルを示しています。

Matched-File-Path、File-Typ、File-Labelはファイルの情報です。それぞれファイルのパス、ファイルの種別(ファイル、ディレクトリなど)、設定されているラベルを示します。これらが、プロセスがパーミッションを持つファイルの情報になります。

SAME-SELinux-Typeはファイルコンテキストとファイルのタイプが一致しているかどうかを示しています。この情報はファイルコンテキストと実際の値に不整合がないかをチェックする際に用います。この値がNGだとファイルコンテキストと異なるタイプが割り当てられているため、実際にはパーミッションがない状態になっています。

それでは、これらを踏まえてレコードを見てみましょう。

/etc/.*,all files,system_u:object_r:etc_t:s0,/etc/fstab,f,system_u:object_r:etc_t:s0,OK

赤字で示した部分が、httpdプロセスがreadパーミッションを持つファイルのパスです。このように、コマンド1つでプロセスがアクセスできるファイルを調査できます。

Web上からSELinuxの情報を参照する

最後にもう1つ、「SELinux Information Viewer」というツールを紹介します。このツールはWebブラウザ上からSELinuxの情報を参照できます。こちらのサイトから入手できます。

下記の画面では、httpd_tドメインがパーミッションを持つSELinuxタイプのファイルコンテキストを検索しています。

また、ファイルコンテキストのファイルパターンにマッチするファイルの一覧を参照することもできます。

おわりに

今回はSELinuxのツールを紹介しました。紹介したツールはMITライセンスで公開されているため、自由に利用できます。興味のある方は、ぜひ1度試してみてください。

株式会社日立製作所
日立製作所入社後、社内システムの開発を担当。現在はOSSソリューションセンタに所属し、セキュリティ分野のOSSを活用したソリューション開発に従事している。

連載バックナンバー

Think ITメルマガ会員登録受付中

Think ITでは、技術情報が詰まったメールマガジン「Think IT Weekly」の配信サービスを提供しています。メルマガ会員登録を済ませれば、メルマガだけでなく、さまざまな限定特典を入手できるようになります。

Think ITメルマガ会員のサービス内容を見る

他にもこの記事が読まれています