Red Hat Training

A Red Hat training course is available for RHEL 8

8.2. 사용자 지정 애플리케이션에 대한 SELinux 정책 생성 및 실행

SELinux로 애플리케이션을 제한하여 호스트 시스템 및 사용자 데이터의 보안을 강화할 수 있습니다. 각 애플리케이션에는 특정 요구 사항이 있으므로 사용 사례에 따라 간단한 데몬을 제한하는 SELinux 정책을 생성하기 위한 이 예제 절차를 수정합니다.

사전 요구 사항

  • selinux-policy-devel 패키지 및 해당 종속 항목은 시스템에 설치됩니다.

절차

  1. 이 예제 절차의 경우 쓰기를 위해 /var/log/messages 파일을 여는 간단한 데몬을 준비합니다.

    1. 새 파일을 생성하고 선택한 텍스트 편집기에서 엽니다.

      $ vi mydaemon.c
    2. 다음 코드를 삽입합니다.

      #include <unistd.h>
      #include <stdio.h>
      
      FILE *f;
      
      int main(void)
      {
      while(1) {
      f = fopen("/var/log/messages","w");
              sleep(5);
              fclose(f);
          }
      }
    3. 파일을 컴파일합니다.

      $ gcc -o mydaemon mydaemon.c
    4. 데몬의 systemd 장치 파일을 생성합니다.

      $ vi mydaemon.service
      [Unit]
      Description=Simple testing daemon
      
      [Service]
      Type=simple
      ExecStart=/usr/local/bin/mydaemon
      
      [Install]
      WantedBy=multi-user.target
    5. 데몬을 설치하고 시작합니다.

      # cp mydaemon /usr/local/bin/
      # cp mydaemon.service /usr/lib/systemd/system
      # systemctl start mydaemon
      # systemctl status mydaemon
      ● mydaemon.service - Simple testing daemon
         Loaded: loaded (/usr/lib/systemd/system/mydaemon.service; disabled; vendor preset: disabled)
         Active: active (running) since Sat 2020-05-23 16:56:01 CEST; 19s ago
       Main PID: 4117 (mydaemon)
          Tasks: 1
         Memory: 148.0K
         CGroup: /system.slice/mydaemon.service
                 └─4117 /usr/local/bin/mydaemon
      
      May 23 16:56:01 localhost.localdomain systemd[1]: Started Simple testing daemon.
    6. 새 데몬이 SELinux에 의해 제한되지 않았는지 확인합니다.

      $ ps -efZ | grep mydaemon
      system_u:system_r:unconfined_service_t:s0 root 4117    1  0 16:56 ?        00:00:00 /usr/local/bin/mydaemon
  2. 데몬에 대한 사용자 지정 정책을 생성합니다.

    $ sepolicy generate --init /usr/local/bin/mydaemon
    Created the following files:
    /home/example.user/mysepol/mydaemon.te # Type Enforcement file
    /home/example.user/mysepol/mydaemon.if # Interface file
    /home/example.user/mysepol/mydaemon.fc # File Contexts file
    /home/example.user/mysepol/mydaemon_selinux.spec # Spec file
    /home/example.user/mysepol/mydaemon.sh # Setup Script
  3. 이전 명령으로 만든 설정 스크립트를 사용하여 새 정책 모듈로 시스템 정책을 다시 빌드합니다.

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

    설정 스크립트에서 restorecon 명령을 사용하여 파일 시스템의 해당 부분의 레이블을 다시 지정합니다.

    restorecon -v /usr/local/bin/mydaemon /usr/lib/systemd/system
  4. 데몬을 재시작하고 이제 SELinux 제한 사항을 실행하는지 확인합니다.

    # systemctl restart mydaemon
    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  5. 이제 데몬이 SELinux에 의해 제한되므로 SELinux는 /var/log/messages 에도 액세스할 수 없습니다. 해당 거부 메시지를 표시합니다.

    # ausearch -m AVC -ts recent
    ...
    type=AVC msg=audit(1590247112.719:5935): avc:  denied  { open } for  pid=8150 comm="mydaemon" path="/var/log/messages" dev="dm-0" ino=2430831 scontext=system_u:system_r:mydaemon_t:s0 tcontext=unconfined_u:object_r:var_log_t:s0 tclass=file permissive=1
    ...
  6. sealert 툴을 사용하여 추가 정보를 얻을 수도 있습니다.

    $ sealert -l "*"
    SELinux is preventing mydaemon from open access on the file /var/log/messages.
    
    *****  Plugin catchall (100. confidence) suggests   **************************
    
    If you believe that mydaemon should be allowed open access on the messages file by default.
    Then you should report this as a bug.
    You can generate a local policy module to allow this access.
    Do allow this access for now by executing:
    # ausearch -c 'mydaemon' --raw | audit2allow -M my-mydaemon
    # semodule -X 300 -i my-mydaemon.pp
    
    Additional Information:
    Source Context                system_u:system_r:mydaemon_t:s0
    Target Context                unconfined_u:object_r:var_log_t:s0
    Target Objects                /var/log/messages [ file ]
    Source                        mydaemon
    …
  7. audit2allow 툴을 사용하여 변경 사항을 제안하십시오.

    $ ausearch -m AVC -ts recent | audit2allow -R
    
    require {
    	type mydaemon_t;
    }
    
    #============= mydaemon_t ==============
    logging_write_generic_logs(mydaemon_t)
  8. audit2allow 에서 제안한 규칙은 특정 경우 올바르지 않을 수 있으므로 출력의 일부만 사용하여 해당 정책 인터페이스를 찾습니다. macro-expander 툴을 사용하여 logging_write_generic_logs(mydaemon_t) 매크로를 검사하여 매크로에서 제공하는 모든 허용 규칙을 확인합니다.

    $ macro-expander "logging_write_generic_logs(mydaemon_t)"
    allow mydaemon_t var_t:dir { getattr search open };
    allow mydaemon_t var_log_t:dir { getattr search open read lock ioctl };
    allow mydaemon_t var_log_t:dir { getattr search open };
    allow mydaemon_t var_log_t:file { open { getattr write append lock ioctl } };
    allow mydaemon_t var_log_t:dir { getattr search open };
    allow mydaemon_t var_log_t:lnk_file { getattr read };
  9. 이 경우 로그 파일 및 해당 상위 디렉터리에 대한 읽기 및 쓰기 액세스 권한만 제공하므로 제안된 인터페이스를 사용할 수 있습니다. 유형 적용 파일에 해당 규칙을 추가합니다.

    $ echo "logging_write_generic_logs(mydaemon_t)" >> mydaemon.te

    또는 인터페이스를 사용하는 대신 이 규칙을 추가할 수 있습니다.

    $ echo "allow mydaemon_t var_log_t:file { open write getattr };" >> mydaemon.te
  10. 정책을 다시 설치합니다.

    # ./mydaemon.sh
    Building and Loading Policy
    + make -f /usr/share/selinux/devel/Makefile mydaemon.pp
    Compiling targeted mydaemon module
    Creating targeted mydaemon.pp policy package
    rm tmp/mydaemon.mod.fc tmp/mydaemon.mod
    + /usr/sbin/semodule -i mydaemon.pp
    ...

검증

  1. 애플리케이션이 SELinux에 의해 제한된 실행을 확인합니다. 예를 들면 다음과 같습니다.

    $ ps -efZ | grep mydaemon
    system_u:system_r:mydaemon_t:s0 root        8150       1  0 17:18 ?        00:00:00 /usr/local/bin/mydaemon
  2. 사용자 지정 애플리케이션에서 SELinux 거부를 유발하지 않는지 확인합니다.

    # ausearch -m AVC -ts recent
    <no matches>

추가 리소스