[여기보기] 파일과 디렉터리에는 정확한 소유권과 적당한 권한을 부여하라

| 2022-08-24

[여기보기]는 “여기서 보안의 기본을 챙기고 가자”의 약자로, 개발 과정에서 꼭 최소한으로 챙기면 좋을 보안 기초 설정을 앞으로 하나씩 공유할 예정입니다. 기초 내용이 주를 이루겠지만, 혹시라도 빼먹고 계신 것이 없는지 가끔 한 번씩 둘러봐 주세요.

안녕하세요, 넷마블 보안실 보안개발팀 이석진입니다. 

리눅스에서는 기본적으로 ‘find’, ‘chown’, ‘chmod’만 잘 써도 위협 요소 대부분 방어할 수 있습니다. 파일과 디렉터리마다 정확한 소유권과 적당한 권한이 부여된 것만으로도 허가받지 않은 사용자가 의도한 악의적인 활동은 기본적으로 차단할 수 있기 때문입니다. 그래서 리눅스에서는 어떤 조처를 하느냐보다 무엇을 왜 했는지 이해하고 명확한 기준을 세우는 것이 중요합니다. 이유와 기준만 확실하다면, 나머지 설정은 그에 따라가기만 하면 되니까요.

이번에는 조금 특별한 소유권 관계와 권한이 어떤 영향을 주는지 살펴보겠습니다.

소유자, 특수 권한, 기본 권한

소유자가 없는 것도 문제

종종 퇴사자 계정을 정리하는 과정에서 관리 소홀로 인해 소유자가 존재하지 않는 파일이나 디렉터리가 생깁니다. (당연히 해킹 공격자가 만든 악의적인 파일일 수도 있습니다.) 

이런 파일이나 디렉터리가 영향을 끼칠 범위는 말 그대로 예측 불가가 됩니다. 그래서 존재 목적에 따라 악영향을 줄 가능성이 매우 높으므로 소유자가 존재하지 않는 파일이나 디렉터리는 삭제 또는 소유자 지정 등으로 보호해야 합니다.

마치 소유자와 소유 그룹 이름이 ‘1002’인 척 조회되는 모습

조치방안

소유자나 소유 그룹이 없는 파일이나 디렉터리는 ‘find’ 명령어에서 ‘nouser’와‘nogroup’ 옵션으로 한 번에 찾을 수 있습니다.

$ find / -nouser -o -nogroup
소유자나 소유 그룹이 없는 파일과 디렉터리 조회 결과

소유자나 소유 그룹이 없는 파일과 디렉터리를 찾았습니다. 이제 각자 해당 파일이나 디렉터리가 꼭 필요한지 히스토리를 추적한 후에 소유자를 새로 부여하거나 삭제하면 됩니다.

// 삭제
$ rm <파일이나 디렉터리 이름>

// 소유자 변경
$ chown <소유자>:<소유 그룹> <파일이나 디렉터리 이름>

특수 권한 – SUID, SGID, StickyBit

SUID(Setuid), SGID(Setgid), StickyBit는 설정된 파일에서 특정 작업을 수행하기 위해 일시적으로 소유자나 소유 그룹의 권한을 얻는 기능입니다. 대표적으로 비밀번호 변경할 때 동작합니다. ‘passwd’ 명령어로 비밀번호를 바꿀 때, 새로 입력한 비밀번호는 ‘/etc/shadow’ 파일에 저장합니다. 즉, ‘passwd’ 명령어를 사용할 때 일시적으로 ‘/etc/shadow’ 파일에 접근 권한과 쓰기 권한이 있는 소유자 권한을 부여받는다는 의미가 됩니다. 

Setuid에 대한 자세한 설명은 아래 링크를 참고해주세요.

Setuid가 발동할 때 파일 소유자의 권한을 그대로 사용하므로, 만약 파일 소유자가 루트(root)라면 절대 권한을 함께 받습니다. 물론 실행하는 동안만 받는 권한이지만, 실행했다는 자체만으로도 무수한 여파를 불러올지도 모릅니다. 정상 서비스를 훼방하고도 남을 만큼 막대한 권한을 가진 셈이니까요. 그래서 주요 실행 파일에는 이 권한이 꼭 필요한지 꼭 확인해야 합니다.

조치 방안

SUID와 SGID가 설정된 실행 파일은 ‘find’ 명령어와 추가 옵션으로 한 번에 찾을 수 있습니다.

$ find / -user root -type f \( -perm -4000 -o -perm -2000 \) -xdev -exec ls -al {} \;
SUID와 SGID가 설정된 실행 파일

검토 대상 파일 목록은 찾았습니다. 이 중에서 부여된 권한이 문제일 땐, 권한 회수가 가장 쉬운 답입니다.

$ chmod -s <파일 이름>

하지만 반드시 사용해야 하는 경우도 있습니다. 그럴 땐 특정 그룹에서만 사용할 수 있게 제한해두고, 일반 사용자는 Setuid를 사용할 수 없도록 제한해두시길 추천합니다.

$ chgrp <특정 그룹 이름> <Setuid를 설정할 파일 이름>
$ chmod 4750 <Setuid를 설정할 파일 이름>

단, 무분별한 SUID와 SGID 제거는 운영체제 동작이나 애플리케이션 실행에 영향을 줄 수 있으므로 서비스 정상 작동 유무를 꼭 확인하며 조절해야 합니다.

기본 권한 – umask

‘umask’는 파일이나 디렉터리를 생성할 때 부여받는 기본 권한을 지정하는 명령어입니다. 기본으로 부여받는 권한으로 인해 시스템이 악용될 우려가 있다면 새로 생성하는 파일이나 디렉터리에 과도한 권한이 부여되지 않도록 ‘umask’ 값을 조절해주는 것이 좋습니다.

계산 방법

설정하는 ‘umask’ 값은 하나지만, 파일과 디렉터리 사이 권한은 서로 다르게 적용됩니다.

  • 파일:
    umask + 새로 생성한 파일이 부여받는 기본 권한 = 666
  • 디렉터리:
    umask + 새로 생성한 디렉터리가 부여받는 기본 권한 = 777

위에서 설명한 ‘SUID’, ‘SGID’, ‘StickyBit’는 ‘umask’ 설정 영향을 받지 않습니다.

조치 방안

‘umask’ 값이 ‘022’가 되면, 파일은 ‘644’, 디렉터리는 ‘755’ 권한을 받습니다. 즉, 022보다 큰 숫자로 설정했을 때, 소유자만 쓰기 권한을 받을 수 있다는 의미가 됩니다. 그래서 통상적으로 ‘022’ 이상을 사용하는 것이 좋습니다.

루트(root) 계정을 포함한 ‘umask’ 기본 설정을 바꾸는 파일은 리눅스 종류나 조직 내부 기본 보안 설정마다 다를 수 있습니다. 주로 ‘/etc/bash.bashrc’, ‘/etc/profile’, ‘/etc/bashrc’ 등을 활용합니다. 루트를 제외한 개별 계정 설정은 각 계정의 홈 디렉터리에서 설정할 수 있습니다.

// 루트 계정을 포함한 전체 계정 모두에게 동일한 권한 부여 시,
$ vi [umask 설정 파일]

umask 022


// 루트 계정과 일반 사용자 계정에 서로 다른 권한 부여 시,
$ vi [umask 설정 파일]

if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
       umask 002 # 일반 사용자 계정에 부여할 권한
else
       umask 022 # 루트 계정에 부여할 권한
fi

홈 디렉터리

리눅스에서는 모든 계정에 할당된 홈 디렉터리가 있습니다. 시스템 계정은 각기 목적에 맞는 디렉터리를 홈 디렉터리로 쓰지만, 사용자 계정은 대부분 ‘/Home’ 디렉터리 하위에 있습니다. 그리고 각 사용자별 홈 디렉터리 안에는 설정 파일과 로그성 파일이 있습니다. 당연하게도 이 파일들이 변조되면, 정상적인 서비스 이용에 제한이 생길 수 있습니다.

홈 디렉터리 소유자 및 권한

이 부분은 짧은 설명도 필요 없을 것 같습니다. 홈 디렉터리 소유자는 당연히 해당 계정이어야 하고, 접근도 해당 계정만 할 수 있어야 합니다. 종종 배치 파일을 실행하거나 설정 파일을 읽어와야 할 수 있으므로 읽기 권한과 실행 권한은 상황에 맞춰 최소한으로 부여하는 경우도 있습니다만, 홈 디렉터리 내 설정 파일이 비인가자에 의해 변조되는 것을 꼭 방지해야 합니다.

아울러, 사용자 고유 홈 디렉터리가 아닌 다른 디렉터리를 홈 디렉터리로 설정하면 다른 디렉터리 내에 있는 명령어를 사용할 수 있는 비밀의 문이 열립니다. 이 역시 시스템 관리와 보안상 문제가 발생할 여지를 남긴다는 것을 유념해야 합니다. 

상대적으로 최근 버전 리눅스에서는 사용자 계정에 설정된 홈 디렉터리가 없거나, 권한에 맞지 않는 디렉터리가 홈 디렉터리로 설정된 경우에 대비해 일부 대처가 돼 있습니다. 해당 사용자 계정으로 로그인 시도하면, 접근 허용 유무가 확인되지 않은 기본 계정의 홈 디렉터리(우분투에서는 ‘/home/ubuntu’)로 진입하니까요. 또한 로그인 실패로 끝나는 디렉터리도 있긴 합니다. 그럼에도 불구하고 접근 허용 유무가 확인되지 않은 다른 사용자의 홈 디렉터리로 기본 진입하는 케이스가 존재한다는 사실만으로도 두통이 옵니다.

조치 방안

홈 디렉터리가 없는 사용자 계정은 삭제하거나, 올바른 홈 디렉터리 위치를 입력해두길 권합니다.

// 사용자 계정 삭제
$ userdel <사용자 이름>
$ vi /etc/passwd

//  홈 디렉터리를 잘못 설정한 케이스
iamgroot:x:1001:1001:,,,:/:/bin/bash
iamgroot:x:1001:1001:,,,::/bin/bash
iamgroot:x:1001:1001:,,,:/var/run:/bin/bash

// 홈 디렉터리가 올바른 케이스 
iamgroot:x:1001:1001:,,,:/home/iamgroot:/bin/bash

환경변수 파일

홈 디렉터리에는 사용자별 시스템 시작 설정 같은 환경변수 파일이 있습니다. 앞서 홈 디렉터리 소유권과 접근 권한을 점검했더라도, 환경변수 파일 접근 권한도 꼭 확인하시는 것이 좋습니다.

  • 환경변수 파일 종류:
    *.profile, .kshrc, .cshrc, .bashrc, .bash_profile, .login, exrc, .netrc 등

홈 디렉터리 환경변수 파일 소유자는 해당 계정 또는 루트(root) 계정이어야 하고, 쓰기 권한 역시 해당 계정 또는 루트 계정이어야 합니다. 

조치 방안

홈 디렉터리 환경변수 파일 소유자가 해당 계정 또는 루트 계정으로 설정돼 있는지 확인 후, 아래 설정 방법에 따라 쓰기 권한 등도 함께 점검하시길 바랍니다.

// 소유자 변경 방법
$ chown <사용자 이름>:<그룹 이름> <파일 이름>

// 일반 사용자 쓰기 권한 제거 방법
$ chmod o-w <파일 이름>

서버 세팅 때 한 번이라도 점검하자

위 사례들은 은근히 흔치 않습니다. 그래서 관련 이슈가 나오면 낯설 수밖에 없습니다. 하지만 조치 방안을 보면, 딱히 어렵거나 특별한 명령어를 쓰지도 않았습니다. 소유권과 권한이 미치는 영향 범위를 파악하고, 수정하는 패턴을 반복했을 뿐이었습니다.

가장 좋은 방법은 주기적인 반복 점검입니다. 하지만 서버 환경은 한번 세팅한 후에는 잘 수정하지 않는 특성도 있으므로, 최초 서버 세팅 때 단 한 번이라도 점검해서 오래 두고 쓸 수 있는 튼튼한 방패를 하나씩 장착하셨으면 좋겠습니다.