리눅스에서는 다른 유닉스 계열 운영체제처럼 파일이나 디렉터리의 권한을 관리할 때 소유자(owner), 그룹(group), 다른 사용자(other) 라는 세 가지 역할에 따라 접근 권한을 부여할 수 있고, 이 작업은 chmod 명령어를 통해 수행한다.

 

이러한 세 가지 역할에 따라 접근 권한을 관리하는 데는 갖가지 제한이 있었다. 일례로 어떤 파일에 대해 alice, bob 사용자에게 읽기 권한만 주고 Eve와 Frank는 읽기/쓰기 권한을 주는 등의 세밀한 권한 조정은 불가능했다.

이같은 문제를 해결하기 위해 리눅스 커널과 파일 시스템에 접근 제어 목록(ACL; Access Control List)을 구현했고 cp, mv 같은 파일을 다루는 유틸리티도 ACL 에 맞게 수정됐다.

접근 제어 목록은 파일 시스템의 속성으로 부여되므로 ext1, ext2 같은 이전의 파일 시스템에서는 사용할 수 없다.

ACL 설정

ACL 은 access ACL 과 기본 ACL 두 가지 형식이 있다. access ACL 은 지정한 파일이나 디렉터리에 대해 설정한 접근 제어 목록이며 기본 ACL 은 디렉터리에만 지정할 수 있고 필수 사항은 아니다.

디렉토리에 들어있는 파일에 access ACL 이 설정돼 있지 않으면 디렉토리에 지정된 기본 ACL 을 사용하게 된다.  ACL 은 사용자별, 그룹별, 유효 접근 권리 마스크(effective rights mask) 별, 그리고 다른 사용자(other)에 대해 설정할 수 있다.

ACL 을 설정하는 명령어는 setfacl 이다. 이제 setfacl 의 사용법에 대해서 알아 보자.

 

ACL 추가/변경

-m 옵션을 사용하면 파일이나 디렉터리의 ACL 을 추가 또는 변경할 수 있으며 setfacl -m rules files 와 같은 형식으로 사용하면 된다. rule 은 필수 항목이며 다음과 같이 설정할 수 있다.

  • u:uid:perms
    특정 사용자를 대상으로 ACL 을 설정한다. 대상 사용자는 사용자 ID나 UID(숫자)로 지정하면 되며 유효한 사용자여야 한다.
  • g:gid:perms
    그룹을 대상으로 권한을 지정하며, 대상 그룹은 그룹 명이나 GID(숫자) 로 지정하며 유효한 그룹이여야 한다.
  • o:perms
    다른 사용자(other)에 대해 ACL 을 지정한다. perms 에 지정하는 권한은 r(읽기), w(쓰기), x(실행) 세 가지로 나눠지며 여러 권한을 지정할 경우 권한 문자를 이어서 써주면 된다. 예를 들어 읽기, 쓰기를 허용할 경우 rw 를 지정하면 된다.
ACL 삭제

-x, --remove 옵션을 사용하면 ACL 을 삭제할 수 있다. -m 과 마찬가지로 rules 과 파일명을 주게 되어 있으나 권한 항목은 지정할 수 없으며, 지정된 사용자와 그룹의 모든 권한을 삭제한다.

사용예

일반 사용자는 /etc/sysconfig/iptables 파일의 내용을 볼 수가 없다. 따라서 lesstif 사용자에게만 /etc/sysconfig/iptables 파일을 볼 수 있는 권한을 부여해 보자.

setfacl -m u:lesstif:r /etc/sysconfig/iptables
BASH

lesstif 사용자로 다음 명령어를 수행하여 ACL 이 제대로 동작하는지 확인해 보자.

cat /etc/sysconfig/iptables
BASH

 

lesstif 사용자에게 부여한 /etc/sysconfig/iptables 의 모든 권한을 삭제해 보자. 

setfacl -x u:lesstif /etc/sysconfig/iptables
BASH

이제 lesstif 사용자가  /etc/sysconfig/iptables 을 읽으려고 할 경우 "Permission denied" 에러가 발생하게 된다.

 

/project/config 파일은 devel 그룹은 읽고 쓸 수 있고 lesstif 사용자는 읽을 수만 있도록 설정해 보자.

setfacl -m g:devel:rw /project/config
setfacl -m u:lesstif:r /project/config
BASH

이제 devel 그룹에 속한 사용자로 로그인한 후에 편집기로 /project/config 를 수정한 후에 저장하고 lesstif 사용자로도 마찬가지 작업을 해 보면 후자는 실패하고 ACL 이 예상한 대로 동작하는 것을 확인할 수 있다.

기본 ACL 설정

기본 ACL 설정은 rules 항목 앞에 d 문자를 붙이면 된다. 디렉터리에만 가능하므로 파일에 지정할 경우 에러가 발생한다.  

ACL 확인

getfacl 명령어로 파일이나 디렉터리에 설정된 ACL 을 확인할 수 있다. 일례로 시스템 로그가 쌓이는 /var/log 의 ACL 을 확인해 보자. 

getfacl /var/log
 
getfacl: Removing leading '/' from absolute path names
# file: var/log
# owner: root
# group: root
user::rwx
group::r-x
other::r-x
BASH

/var/log 의 소유자는 root 이고 그룹도 root 이다. 소유자는 읽기(r), 쓰기(w), 실행(x) 권한을 갖고 있고 그룹과 다른 사용자에게는 읽기(r), 실행(x) 권한이 부여돼 있음을 확인할 수 있다.

 

ACL의 활용

리눅스나 유닉스를 관리할 경우 좋은 습관중에 하나는 루트로 작업하는 것을 최소화하는 것이다. 불편하더라도 일반 사용자로 로그인하여 작업하고 꼭 루트 권한이 필요할 경우에만 루트 권한을 획득하여 작업하거나 sudo 명령어로 루트 권한이 필요한 명령어만 별도로 실행하는 것이 큰 사고나 실수를 방지하는 좋은 작업 습관이다.

 

일반 사용자로 웹 서버 로그 보기

CentOS에 설치되는 아파치 웹서버의 경우 일반 사용자는 로그 파일을 볼 수 없게 되어 있다. 단순히 웹서버 로그를 보기 위해 매번 root 로 로그인하는 것은 바람직하지 않지만 모든 사용자가 로그 파일을 볼 수 있는 것도 바람직한 상황은 아니다. 이제 setfacl 을 이용하여 lesstif 라는 사용자는 아파치 웹서버 로그를 볼 수 있게 설정해 보자.

웹서버 로그가 저장되는 /etc/httpd/logs 는 실제로는 /var/log/httpd 에 대한 심볼릭 링크이다. 먼저 getfacl 의 접근 권한 설정을 확인해 보자.

 getfacl /var/log/httpd/
 
getfacl: Removing leading '/' from absolute path names
# file: var/log/httpd/
# owner: root
# group: root
user::rwx
group::---
mask::---
other::---
BASH

 

소유자인 root 를 제외한 일반 사용자는 아무 권한이 없으므로 /var/log/httpd 디렉토리에 대해 ls 로 파일 목록을 조회조차 할 수 없다. 이제 lesstif 사용자에게 읽기 권한을 부여해 보자. 대상이 디렉터리이므로 읽기(r), 실행(x) 속성을 같이 줘야 해당 디렉터리의 내용들을 볼 수 있다.

setfacl -m u:lesstif:rx /var/log/httpd/
BASH

 

이제 lesstif 사용자는 tail -f /var/log/httpd/error_log  명령으로 아파치 웹 서버로의 로그를 읽을 수 있고 다른 사용자는 기존처럼 읽기가 불가능하므로 웹 서버 로그를 보려고 루트로 로그인 할 필요가 없다.

 

웹 서버가 워드프레스 접근

웹 서버나 기타 어플리케이션 서버 설정시 서버를 구동한 계정과 컨텐츠를 제공하는 계정이 다른 경우가 있을 수 있다.

예로 유명한 CMS 인 워드프레스를 /var/www/wordpress 에 설치했을 경우 해당 디렉터리가 루트 소유일 필요는 없고 오히려 일반 사용자 소유로 하는게 변경 작업도 간편하고 보안 측면에서도 유리하다.

그래서 시스템에 wordpress 라는 계정을 만들고 /var/www/wordpress 디렉터리의 소유자를 wordpress 로 변경했을 경우 다음과 같은 문제가 발생한다.

  • 권한 문제로 인해 워드프레스에서 글 작성시 첨부 파일 업로드 실패

위 문제는 소유자는 wordpress 인데 웹 서버를 구동한 계정은 apache 계정이므로 워드프레스의 uploads 폴더에 쓰지를 못 해서 발생하는 문제이다.

이 경우 uploads 폴더를 만들고 아파치 웹 서버만 uploads 폴더에 쓰기 권한을 부여하면 /tmp 처럼 모두에게 쓰기 권한을 주지 않고 특정 계정에게만 권한을 부여해 이 같은 문제를 해결할 수 있다.

mkdir /var/www/wordpress/wp-content/uploads
setfacl -m u:apache:rwx /var/www/wordpress/wp-content/uploads
BASH

 

웹 서버가 사용자 디렉터리 읽기

nginx나 apache httpd 등의 웹 서버가 사용자 디렉터리 읽기 위해서는 우선 다음과 같은 SELinux boolean 설정이 필요하다.

setsebool -P httpd_read_user_content 1
CODE


위 설정이 있어도 사용자 디렉터리의 기본 퍼미션은 700 이므로 웹 서버가 접근할 수 없으므로 다음과 같이 setfacl 명령어를 실행해 주면 된다.

setfacl -m u:nginx:rx /home/lesstif/
CODE



이처럼 ACL 을 이해하고 setfaclgetfacl 의 사용법을 알면 파일/디렉터리별 세밀한 접근 제어 설정을 통해 루트로 수행해야 하는 작업을 최소화하고 잘못된 모드 설정으로 인한 보안 취약점을 방지할 수 있다.