LoginSignup
2
4

More than 5 years have passed since last update.

CentOS7上で SE Linux の独自ラベル、独自ドメイン、ルール(allow)を定義してみた

Last updated at Posted at 2018-01-23

やってみたこと

CentOS7上で、

  • 独自タイプ定義
  • 独自ドメイン定義
  • ドメイン遷移定義
  • 独自 allow ルール定義

をやってみました。
ネット上にも資料が少なく、かなり苦労しました…
#既存マクロの一部を書き換えての対応が必要だったり…

[SE Linux] 実習環境 on CentOS7

(事前準備)

関連パッケージのインストール

$ sudo yum install selinux-policy-mls
$ sudo yum install selinux-policy-devel

/etc/selinux/config書き換え

SELINUX=permissive ※絶対にenforcingのままにしないこと!
SELINUXTYPE=mls ※selinux-policy-mlsをインストールしないと起動不可になるよ!

こんな風にします(ファイルの配置とラベル)

  /home/tomonobu/
    + mypolicy/ ......... 独自ポリシー置場
    |   + Makefile    ... ビルド用メイクファイル
    |   + mypolicy.te ... teファイル
    |   + mypolicy.fc ... fcファイル
    |
    + myapp/myapp ... ドメイン (my_secure_app_t) / タイプ (my_secure_app_exec_t)
    + secure_data ... タイプ   (my_secure_data_t)
        + hello.txt

作業内容(ほとんど作業メモですが)

/home/tomonobu/secure_data に my_secure_data_t を付与

  $ mkdir mypolicy
  $ cd mypolicy
  $ touch mypolicy.te
  $ touch mypolicy.fc
  $ cp /usr/share/selinux/devel/Makefile .

  $ vi mypolicy.te
  -----
  module mypolicy 1.0;          # mypolicyはファイル名と合わせる(合わせないとエラー)
  type my_secure_data_t;
  file_type(my_secure_data_t)
  -----

  $ vi mypolicy.fc
  -----
  /home/tomonobu/secure_data(/.*)? gen_context(system_u:object_r:my_secure_data_t, s0)
  -----

  $ make
  $ tree
  .
  ├─ Makefile
  ├─ mypolicy.fc
  ├─ mypolicy.if *
  ├─ mypolicy.pp *
  ├─ mypolicy.te
  └─ tmp *
      ├─ all_interfaces.conf *
      ├─ iferror.m4 *
      └─ mypolicy.tmp *

makeすると * のファイルが出来上がる


  $ sudo semodule -i mypolicy.pp # ポリシーのインストール

  $ cd
  $ mkdir secure_data
  $ restoreconf -RF .
  $ ls -Z
  -rwxrwxr-x. tomonobu tomonobu user_u:object_r:user_home_t:s0   a.out
  -rw-rw-r--. tomonobu tomonobu user_u:object_r:user_home_t:s0   hello.c
  drwxrwxr-x. tomonobu tomonobu user_u:object_r:user_home_t:s0   mypolicy
  drwxrwxr-x. tomonobu tomonobu user_u:object_r:user_home_t:s0 secure_data
                                                ^^^^^^^^^^^

独自タイプ(my_secure_data_t)がついていない(想定内)
ホームディレクトリ配下に独自ラベルを付けるためには、以下の対応が必要

  $ cd /etc/selinux/mls/contexts/files
                    ^^^
                    SELINUXTYPEと連動する
  $ vi file_contexts
  $ cat file_contexts | grep tomonobu
  /home/tomonobu/secure_data(/.*)?        system_u:object_r:my_secure_data_t:s0

  $ sudo vi file_contexts          ... 上記の行を消す
  $ sudo vi file_contexts.homedirs ... 上記の行を追加する

  $ cd
  $ restorecon -RF .
  $ ls -Z
  -rwxrwxr-x. tomonobu tomonobu user_u:object_r:user_home_t:s0   a.out
  -rw-rw-r--. tomonobu tomonobu user_u:object_r:user_home_t:s0   hello.c
  drwxrwxr-x. tomonobu tomonobu user_u:object_r:user_home_t:s0   mypolicy
  drwxrwxr-x. tomonobu tomonobu system_u:object_r:my_secure_data_t:s0 secure_data
                                                  ^^^^^^^^^^^^^^^^
                                                  OK!!

audit.logの確認

  $ echo "hello" > secure_data/hello.txt

  $ su
  # cd /var/log/audit

  # grep hello audit.log
  type=AVC msg=audit(1516640677.824:259): avc:  denied  { add_name } for  pid=1108 comm="bash" name="hello.txt" scontext=user_u:user_r:user_t:s0 tcontext=system_u:object_r:my_secure_data_t:s0 tclass=dir
  type=AVC msg=audit(1516640677.824:259): avc:  denied  { create } for  pid=1108 comm="bash" name="hello.txt" scontext=user_u:user_r:user_t:s0 tcontext=user_u:object_r:my_secure_data_t:s0 tclass=file
  type=AVC msg=audit(1516640677.824:259): avc:  denied  { write open } for  pid=1108 comm="bash" path="/home/tomonobu/secure_data/hello.txt" dev="dm-0" ino=17104421 scontext=user_u:user_r:user_t:s0 tcontext=user_u:object_r:my_secure_data_t:s0 tclass=file

  # grep secure_data audit.log もしてみていろいろ確認してみよう

myappの作成と audit.log の確認

  $ cd
  $ mkdir myapp
  $ cd myapp
  $ vi myapp.c

/home/tomonobu/secure_data 以下のファイルを触りに行くコードを書きます。
(hello.txtは echo "hello" > hello.txt とでもして作っておいてください)

  #include <stdio.h>

  #define SIZE 256

  int main(int argc, char** argv) {
      FILE *fp;
      char buf[SIZE];

      fp = fopen("/home/tomonobu/secure_data/hello.txt", "r");
      if (NULL == fp) {
          printf("ERROR : fopen\n");
          return -1;
      }
      else {
          while (fgets(buf, SIZE, fp) != NULL) {
              printf("%s", buf);
          }
      }
      fclose(fp);

      return 0;
  }

実行して、audit.log の avcエラーを確認してみます。

  $ echo "hello" > /home/tomonobu/secure_data/hello.txt
  $ gcc myapp.c -o myapp
  $ myapp

  $ su
  # cd /var/log/audit
  # grep myapp audit.log
  type=AVC msg=audit(1516641337.815:295): avc:  denied  { read } for  pid=1448 comm="myapp" name="hello.txt" dev="dm-0" ino=17104421 scontext=user_u:user_r:user_t:s0 tcontext=user_u:object_r:my_secure_data_t:s0 tclass=file

※ myapp が hello.txt を読もうとして read の avcエラー が出ている (期待動作)

myappにドメインの付与(ドメインの準備と付与)

  $ cd
  $ cd mypolicy

  $ vi mypolicy.te
  -----
  policy_module(mypolicy, 2.0)

  type my_secure_data_t;
  files_type(my_secure_data_t)

  type my_secure_app_exec_t;
  files_type(my_secure_app_exec_t)

  type my_secure_app_t;
  domain_type(my_secure_app_t)
  domain_entry_file(my_secure_app_t, my_secure_app_exec_t)
  unconfined_domtrans_to(my_secure_app_t, my_secure_app_exec_t)

  allow my_secure_app_t my_secure_data_t:file read_file_perms;
  -----

  $ vi mypolicy.fc
  -----
  /home/tomonobu/secure_data(/.*)? gen_context(system_u:object_r:my_secure_data_t, s0)
  /home/tomonobu/myapp/myapp gen_context(system_u:object_r:my_secure_app_exec_t, s0)
  -----

  $ make clean
  $ make
  $ sudo semodule -i mypolicy.pp
  Failed to resolve typeattributeset statement at /etc/selinux/mls/tmp/modules/400/mypolicy/cil:22
  semodule:  Failed!

※ Fail...
※ なんとなく、過去に自分で作ったラベルと当たっちゃっててエラーになっている気がする...

(事実を知った俺より過去の俺へ...)
違う
mlsには unconfied_t の定義が無いのに、
unconfied_domtrans_toマクロ内で利用しているので "Failt to resolve typeatributeset" となっている。
(エラー原因のラベル名をエラーメッセージに出してほしいよね...)

unconfined_domtrans_to(my_secure_app_t, my_secure_app_exec_t)
の行があると、上記エラーが出る。
逆にこの一行を消すと上記エラーは発生しない。(一行ずつコメントアウトして確かめたよ... orz)

http://linux.k-sakabe.com/LinuxSecurityEx.pdf
とか
https://qiita.com/bonon0/items/b027b673ef98af3ed4fd
とか
みても、正しそうだけどなぁ...

/usr/share/selinux/devel/ にて grep "unconfined_domtrans_to"

./devel/include/roles/unconfineduser.if:interface(unconfined_domtrans_to', ※これを見てみると...
./devel/include/roles.xml:
./devel/policy.xml:

※マクロ定義かな??

/usr/share/selinux/devel/include/roles/unconfineduser.if

  ########################################
  ## <summary>
  ##      Allow unconfined to execute the specified program in
  ##      the specified domain.
  ## </summary>
  ## <desc>
  ##      <p>
  ##      Allow unconfined to execute the specified program in
  ##      the specified domain.
  ##      </p>
  ##      <p>
  ##      This is a interface to support third party modules
  ##      and its use is not allowed in upstream reference
  ##      policy.
  ##      </p>
  ## </desc>
  ## <param name="domain">
  ##      <summary>
  ##      Domain to execute in.
  ##      </summary>
  ## </param>
  ## <param name="entry_file">
  ##      <summary>
  ##      Domain entry point file.
  ##      </summary>
  ## </param>
  #
  interface(`unconfined_domtrans_to',`
          gen_require(`
                  type unconfined_t;
          ')

          domtrans_pattern(unconfined_t,$2,$1)
  ')

ん?
mlsだと、unconfied_t が定義されていなくてこけている??? <-- 正解

ここを

  interface(`unconfined_domtrans_to',`
          gen_require(`
                  type user_t;
          ')

          domtrans_pattern(user_t,$2,$1)
  ')

に変更してみた。(ps -Z すると、bashやpsが user_t で動作している様子なので)

==> 通った!!!

  $ cd
  $ cd myapp
  $ ./myapp

で audit.log の確認

type=AVC msg=audit(1516646161.634:861): avc:  denied  { search } for  pid=3023 comm="myapp" name="secure_data" dev="dm-0" ino=17104418 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_home_t:s0 tclass=dir
type=AVC msg=audit(1516646161.634:861): avc:  denied  { read } for  pid=3023 comm="myapp" name="hello.txt" dev="dm-0" ino=17104421 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_home_t:s0 tclass=file
type=AVC msg=audit(1516646161.634:861): avc:  denied  { open } for  pid=3023 comm="myapp" path="/home/tomonobu/secure_data/hello.txt" dev="dm-0" ino=17104421 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_home_t:s0 tclass=file
type=AVC msg=audit(1516646161.636:862): avc:  denied  { getattr } for  pid=3023 comm="myapp" path="/home/tomonobu/secure_data/hello.txt" dev="dm-0" ino=17104421 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_home_t:s0 tclass=file
type=AVC msg=audit(1516646161.636:863): avc:  denied  { getattr } for  pid=3023 comm="myapp" path="/dev/pts/0" dev="devpts" ino=3 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_devpts_t:s0 tclass=chr_file

ログアウト・ログイン で 再度試す

  type=AVC msg=audit(1516646161.636:863): avc:  denied  { getattr } for  pid=3023 comm="myapp" path="/dev/pts/0" dev="devpts" ino=3 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_devpts_t:s0 tclass=chr_file
  ------
  type=AVC msg=audit(1516646477.318:945): avc:  denied  { read write } for  pid=3087 comm="myapp" path="/dev/pts/0" dev="devpts" ino=3 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_devpts_t:s0 tclass=chr_file
  type=AVC msg=audit(1516646477.321:946): avc:  denied  { getattr } for  pid=3087 comm="myapp" path="/dev/pts/0" dev="devpts" ino=3 scontext=user_u:user_r:my_secure_app_t:s0 tcontext=user_u:object_r:user_devpts_t:s0 tclass=chr_file
  ------

863以降は、hello.txtに対するアクセスエラーは出ていない様子

==> 成功っぽい ★要検証

  • 検証方法-1) mypolicy.teから allow 行を消して検証
  • 検証方法-2) myappを無限ループさせて、ps -Z で ドメインチェック

※ dev/pts/0 についてはこちら
http://piyopiyocs.blog115.fc2.com/blog-entry-663.html

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4