LabHub
배우기 러닝패스 코스

Apache Hadoop — HDFS 와 YARN 을 한 파드에 세우고 운영한다 · 권한과 사용자 · 이론

단순 인증은 당신이 말하는 이름을 그대로 믿는다

LabHub 에서 이어서 보기

한 줄 요약

HDFS 의 권한 검사는 POSIX 와 거의 같고 ACL 까지 갖췄지만, "당신이 누구인가" 는 HDFS 가 판단하지 않는다. 기본 설정인 단순 인증에서는 클라이언트가 말하는 이름을 그대로 믿으므로, 권한은 실수를 막는 장치일 뿐 공격을 막는 장치가 아니다.

개념 지도: "당신이 누구인가" 는 HDFS 가 판단하지 않는다. · 당신은 누구인가(인증) · 그 사람에게 이것이 허락되는가(인가) · 권한 비트.

왜 이 구분이 필요한가

권한에는 두 질문이 들어 있다. 당신은 누구인가(인증)그 사람에게 이것이 허락되는가(인가) 다. HDFS 는 뒤의 질문에는 꼼꼼하게 답한다. 문제는 앞의 질문이다.

[HDFS 권한 안내서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-hdfs/HdfsPermissionsGuide.html)는 사용자 식별 방식을 hadoop.security.authentication 으로 고른다고 설명한다. [core-default.xml](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-common/core-default.xml) 에서 이 값의 기본은 simple 이고, 설명에는 괄호로 "인증 없음" 이라고 붙어 있다. simple 모드에서 클라이언트 프로세스의 신원은 호스트 운영체제가 정하고, 유닉스 계열이면 whoami 의 값이다. 안내서는 한 걸음 더 나가 이렇게 적는다. 어떤 모드든 사용자 신원을 정하는 장치는 HDFS 바깥에 있고, HDFS 안에는 사용자를 만들거나 자격 증명을 처리하는 기능이 없다.

그래서 이 실습에서 환경 변수 HADOOP_USER_NAME=alice 하나만 주면 그 셸은 alice 가 된다. 비밀번호도 없다. 이것이 버그가 아니라 설계라는 것을 [보안 모드 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-common/SecureMode.html)가 분명히 한다. 기본 설정에서는 모든 네트워크 접근을 막아 공격자가 클러스터에 닿지 못하게 하는 것이 여러분의 몫이고, 누가 데이터에 접근하는지 제한하고 싶다면 Kerberos 로 인증을 걸어야 한다는 것이다.

어떻게 동작하나

권한 비트. 파일과 디렉터리마다 소유자, 그룹, 그리고 소유자·그룹 구성원·나머지 사용자 세 부류의 권한이 있다. 파일에서 r 은 읽기, w 는 쓰기와 뒤에 붙이기다. 디렉터리에서 r 은 목록 보기, w 는 안에 만들거나 지우기, x 는 자식에 접근하기다. 실행 파일이라는 개념이 없어 setuid·setgid 비트는 없다. 새로 만든 파일의 소유자는 클라이언트의 신원이고, 그룹은 부모 디렉터리의 그룹을 따른다(BSD 규칙). 여기서 자주 틀린다. 리눅스처럼 사용자의 기본 그룹이 붙는 것이 아니다.

검사 순서. 사용자 이름이 소유자와 같으면 소유자 권한만 본다. 아니면 그룹 목록에 파일의 그룹이 있을 때 그룹 권한만 본다. 둘 다 아니면 나머지 권한을 본다. 위에서 걸리면 아래는 보지 않는다. 또 모든 연산은 경로를 지나갈 수 있어야 한다. /foo/bar/baz 에 닿으려면 /, /foo, /foo/bar 모두에 x 가 있어야 한다.

지우기는 부모의 일이다. 안내서의 연산별 표에서 delete 는 파일 자신이 아니라 부모 디렉터리의 w 를 요구한다. 파일이 읽기 전용이어도 디렉터리에 쓸 수 있으면 지울 수 있다는 뜻이다. 모두가 쓰는 공유 디렉터리에서 남의 파일을 지우지 못하게 하려면 스티키 비트를 건다. 스티키 비트가 걸린 디렉터리에서는 슈퍼유저, 디렉터리 소유자, 파일 소유자만 그 안의 파일을 지우거나 옮길 수 있다.

그룹은 NameNode 가 정한다. 사용자 이름은 클라이언트가 말하지만, 그 사용자가 어느 그룹에 속하는지는 다르다. [그룹 매핑 문서](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-common/GroupsMapping.html)는 HDFS 에서 사용자를 그룹으로 옮기는 일이 NameNode 에서 일어나므로 NameNode 호스트의 시스템 설정이 그룹 소속을 정한다고 적는다. 기본 구현은 운영체제의 그룹 조회를 그대로 쓴다. 또 HDFS 는 파일의 사용자와 그룹을 숫자 ID 가 아니라 문자열로 저장한다. 그래서 finance 그룹이 NameNode 기계에 없으면 클라이언트 쪽에 아무리 그룹을 만들어도 HDFS 는 모른다. 조회 결과는 기본 300초 동안 캐시되므로, 그룹에 사람을 넣은 직후에는 옛 소속으로 검사될 수 있다.

슈퍼유저. NameNode 프로세스와 같은 신원이 슈퍼유저이고, 슈퍼유저에게는 권한 검사가 실패하지 않는다. [hdfs-default.xml](https://hadoop.apache.org/docs/r3.5.0/hadoop-project-dist/hadoop-hdfs/hdfs-default.xml) 의 dfs.permissions.superusergroup(기본 supergroup) 구성원도 슈퍼유저다. NameNode 를 root 로 띄운 이 실습에서는 root 가 슈퍼유저다.

ACL — 조직도와 다른 예외를 표현하기

권한 비트는 "소유자 하나, 그룹 하나" 만 표현한다. 재무 폴더를 finance 그룹에 열고, 감사 담당 bob 한 사람에게만 읽기를 더 주고 싶다면 비트로는 안 된다. 그래서 ACL 이 있다. dfs.namenode.acls.enabled 는 3.5.0 에서 기본 true 다.

hdfs dfs -chown alice:finance /proj/financehdfs dfs -chmod 750 /proj/financehdfs dfs -setfacl -m user:bob:r-x /proj/finance          # bob 에게 목록과 통과hdfs dfs -setfacl -m default:user:bob:r-x /proj/finance  # 앞으로 만들 자식에게 상속hdfs dfs -getfacl /proj/finance

ACL 이 붙으면 검사 순서에 두 칸이 끼어든다. 소유자 다음에 이름 붙은 사용자 항목을, 그룹 다음에 이름 붙은 그룹 항목을 본다. 이 둘과 이름 없는 그룹 항목은 mask 로 한 번 더 걸러진다. mask 는 확장 항목이 줄 수 있는 권한의 상한이다. ACL 이 있는 파일에 chmod 를 하면 그룹 비트가 아니라 mask 가 바뀐다는 점이 함정이다. chmod 700 한 번에 bob 의 읽기가 조용히 막힌다.

기본(default) ACL 은 디렉터리에만 있고, 새 자식이 만들어질 때 복사된다. 안내서는 복사가 만드는 순간에만 일어나고, 뒤에 부모의 기본 ACL 을 바꿔도 이미 있는 자식은 바뀌지 않는다고 적는다. 그래서 기존 파일에 권한을 주려면 setfacl -R 로 따로 돌려야 한다. 한 파일에 달 수 있는 항목도 접근 ACL 32개, 기본 ACL 32개로 제한되고, ACL 이 달린 파일은 NameNode 메모리를 더 쓴다. 안내서가 권하는 방식은 대부분을 권한 비트로 해결하고 예외 몇 개만 ACL 로 얹는 것이다.

현장에서 만나는 모습

첫째, "권한을 막았는데 누가 읽었다." 단순 인증 클러스터에서는 누구든 자기 이름을 alice 라고 말할 수 있다. WebHDFS 도 보안이 꺼져 있으면 user.name 질의 값을 그대로 사용자로 받는다. 권한은 동료의 실수를 막을 뿐이다. 진짜 경계가 필요하면 Kerberos 이고, 그 전까지는 네트워크 접근 통제가 유일한 담이다.

둘째, 새 파일의 그룹이 예상과 다르다. 부모 디렉터리의 그룹을 따르기 때문이다. 팀 폴더의 그룹을 먼저 바로 잡아 두면 그 아래 새 파일이 알아서 따라간다.

셋째, 그룹에 넣었는데 여전히 거절된다. 그룹 소속은 클라이언트가 아니라 NameNode 쪽에서 조회되고 캐시된다. NameNode 기계에 그 그룹과 구성원이 있는지, 캐시가 아직 옛 값을 들고 있지 않은지를 본다.

넷째, 기본 ACL 을 걸었는데 옛 파일은 여전히 못 읽는다. 상속은 만드는 순간의 복사다. 이미 있던 파일에는 따로 걸어야 한다.

다섯째, 권한 검사를 끄는 것은 해결책이 아니다. dfs.permissions.enabled 를 false 로 하면 검사만 꺼지고 모드·소유자·그룹은 그대로 남는다. 안내서는 이 값과 상관없이 chmod·chgrp·chown·setfacl 은 언제나 권한을 검사한다고 적는다.

실무에서 진짜 중요한 것

다음 실습에서 할 것

재무 폴더를 alice 소유, finance 그룹, 750 으로 만들고 alice 로 파일을 올린다. 환경 변수 하나로 사용자를 바꿔 bob 이 거절되는 것을 본 뒤, ACL 로 bob 한 사람에게만 읽기를 열어 실제로 읽히는지 확인한다. 기본 ACL 을 걸고 새로 만든 파일이 그 권한을 물려받는지 보고, 스티키 비트를 건 공유 폴더에서 남의 파일을 지우려다 거절되는 것까지 확인한다. 마지막으로 단순 인증이 막지 못하는 것과 Kerberos 가 필요한 이유를 보고서에 적는다.