접근 제어 매트릭스
접근 제어 매트릭스 (Access Control Matrix)
HBase ACL(접근 제어 목록) 권한이 각 연산에 어떻게 적용되는지 정리한 매트릭스를 다뤄요. 스코프의 해석 방식과 가능한 권한을 먼저 설명하고, Master·Region·Endpoint 등 인터페이스별 권한 매트릭스를 제시할게요.
출처: 문서
본문
ACL 매트릭스 테이블 해석하기 (Interpreting the ACL Matrix Table)
ACL 매트릭스 테이블에는 다음 규약이 사용돼요.
스코프 (Scopes)
권한은 가장 넓은 스코프에서 시작해 가장 좁은 스코프로 평가돼요.
스코프는 데이터 모델의 한 레벨에 해당해요. 넓은 데서 좁은 데로, 스코프는 다음과 같아요.
스코프 (Scopes)
- Global
- Namespace (NS)
- Table
- Column Family (CF)
- Column Qualifier (CQ)
- Cell
예를 들어, 테이블 레벨에서 부여된 권한은 Column Family, Column Qualifier, 또는 cell 레벨에서 이루어진 어떤 부여도 지배해요. 사용자는 테이블의 어느 위치에서든 그 부여가 의미하는 작업을 할 수 있어요. 글로벌 스코프에서 부여된 권한은 모든 것을 지배해요: 사용자는 그 작업을 어디서든 항상 수행할 수 있어요.
권한 (Permissions)
가능한 권한은 다음과 같아요.
권한 (Permissions)
- Superuser — "supergroup" 그룹에 속하며 무제한 접근을 가지는 특별한 사용자
- Admin (A)
- Create (C)
- Write (W)
- Read (R)
- Execute (X)
대부분 권한은 기대한 대로 작동하지만, 다음 주의 사항이 있어요.
Write 권한이 Read 권한을 의미하지는 않아요. 사용자가 읽을 수 없는 데이터를 쓸 수 있도록 하는 것이 가능하며 때로는 바람직해요. 그러한 예 중 하나가 로그 기록 프로세스예요.
hbase:meta 테이블은 다른 부여나 제한과 관계없이 모든 사용자가 읽을 수 있어요. 이것은 HBase가 올바르게 기능하기 위한 요구사항이에요.
CheckAndPut과 CheckAndDelete 연산은 사용자에게 Write와 Read 권한이 모두 없으면 실패해요. Increment와 Append 연산은 Read 접근을 요구하지 않아요. 슈퍼유저는 이름이 암시하듯 모든 가능한 연산을 수행할 권한이 있어요. 그리고 *로 표시된 연산의 경우, 검사는 포스트 훅(post hook)에서 수행되며 접근 검사를 충족하는 결과의 하위 집합만 사용자에게 반환돼요. 다음 테이블은 각 연산을 제공하는 인터페이스로 정렬되어 있어요. 테이블이 낡게 되면, 권한 정확성을 검사하는 단위 테스트는 hbase-server/src/test/java/org/apache/hadoop/hbase/security/access/TestAccessController.java에서 찾을 수 있고, 접근 제어 자체는 hbase-server/src/main/java/org/apache/hadoop/hbase/security/access/AccessController.java에서 검토할 수 있어요.
ACL 매트릭스 (ACL Matrix)
| Interface | Operation | Permissions |
|---|---|---|
| Master | createTable | superuser|global(C)|NS(C) |
| modifyTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| deleteTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| truncateTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| addColumn | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| modifyColumn | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C)|column(A)|column(C) | |
| deleteColumn | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C)|column(A)|column(C) | |
| enableTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| disableTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| disableAclTable | Not allowed | |
| move | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| assign | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| unassign | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| regionOffline | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| balance | superuser|global(A) | |
| balanceSwitch | superuser|global(A) | |
| shutdown | superuser|global(A) | |
| stopMaster | superuser|global(A) | |
| snapshot | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| listSnapshot | superuser|global(A)|SnapshotOwner | |
| cloneSnapshot | superuser|global(A)|(SnapshotOwner & TableName matches) | |
| restoreSnapshot | superuser|global(A)|SnapshotOwner & (NS(A)|TableOwner|table(A)) | |
| deleteSnapshot | superuser|global(A)|SnapshotOwner | |
| createNamespace | superuser|global(A) | |
| deleteNamespace | superuser|global(A) | |
| modifyNamespace | superuser|global(A) | |
| getNamespaceDescriptor | superuser|global(A)|NS(A) | |
| listNamespaceDescriptors* | superuser|global(A)|NS(A) | |
| flushTable | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| getTableDescriptors* | superuser|global(A)|global(C)|NS(A)|NS(C)|TableOwner|table(A)|table(C) | |
| getTableNames* | superuser|TableOwner|Any global or table perm | |
| setUserQuota(global level) | superuser|global(A) | |
| setUserQuota(namespace level) | superuser|global(A) | |
| setUserQuota(Table level) | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| setTableQuota | superuser|global(A)|NS(A)|TableOwner|table(A) | |
| setNamespaceQuota | superuser|global(A) | |
| addReplicationPeer | superuser|global(A) | |
| removeReplicationPeer | superuser|global(A) | |
| enableReplicationPeer | superuser|global(A) | |
| disableReplicationPeer | superuser|global(A) | |
| getReplicationPeerConfig | superuser|global(A) | |
| updateReplicationPeerConfig | superuser|global(A) | |
| listReplicationPeers | superuser|global(A) | |
| getClusterStatus | any user | |
| Region | openRegion | superuser|global(A) |
| closeRegion | superuser|global(A) | |
| flush | superuser|global(A)|global(C)|TableOwner|table(A)|table(C) | |
| split | superuser|global(A)|TableOwner|TableOwner|table(A) | |
| compact | superuser|global(A)|global(C)|TableOwner|table(A)|table(C) | |
| getClosestRowBefore | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| getOp | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| exists | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| put | superuser|global(W)|NS(W)|table(W)|TableOwner|CF(W)|CQ(W) | |
| delete | superuser|global(W)|NS(W)|table(W)|TableOwner|CF(W)|CQ(W) | |
| batchMutate | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| checkAndPut | superuser|global(RW)|NS(RW)|TableOwner|table(RW)|CF(RW)|CQ(RW) | |
| checkAndPutAfterRowLock | superuser|global(R)|NS(R)|TableOwner|Table(R)|CF(R)|CQ(R) | |
| checkAndDelete | superuser|global(RW)|NS(RW)|TableOwner|table(RW)|CF(RW)|CQ(RW) | |
| checkAndDeleteAfterRowLock | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| incrementColumnValue | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| append | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| appendAfterRowLock | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| increment | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| incrementAfterRowLock | superuser|global(W)|NS(W)|TableOwner|table(W)|CF(W)|CQ(W) | |
| scannerOpen | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| scannerNext | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| scannerClose | superuser|global(R)|NS(R)|TableOwner|table(R)|CF(R)|CQ(R) | |
| bulkLoadHFile | superuser|global(C)|TableOwner|table(C)|CF(C) | |
| prepareBulkLoad | superuser|global(C)|TableOwner|table(C)|CF(C) | |
| cleanupBulkLoad | superuser|global(C)|TableOwner|table(C)|CF(C) | |
| Endpoint | invoke | superuser|global(X)|NS(X)|TableOwner|table(X) |
| AccessController | grant(global level) | global(A) |
| grant(namespace level) | global(A)|NS(A) | |
| grant(table level) | global(A)|NS(A)|TableOwner|table(A)|CF(A)|CQ(A) | |
| revoke(global level) | global(A) | |
| revoke(namespace level) | global(A)|NS(A) | |
| revoke(table level) | global(A)|NS(A)|TableOwner|table(A)|CF(A)|CQ(A) | |
| getUserPermissions(global level) | global(A) | |
| getUserPermissions(namespace level) | global(A)|NS(A) | |
| getUserPermissions(table level) | global(A)|NS(A)|TableOwner|table(A)|CF(A)|CQ(A) | |
| hasPermission(table level) | global(A)|SelfUserCheck | |
| RegionServer | stopRegionServer | superuser|global(A) |
| mergeRegions | superuser|global(A) | |
| rollWALWriterRequest | superuser|global(A) | |
| replicateLogEntries | superuser|global(W) | |
| RSGroup | addRSGroup | superuser|global(A) |
| balanceRSGroup | superuser|global(A) | |
| getRSGroupInfo | superuser|global(A) | |
| getRSGroupInfoOfTable | superuser|global(A) | |
| getRSGroupOfServer | superuser|global(A) | |
| listRSGroups | superuser|global(A) | |
| moveServers | superuser|global(A) | |
| moveServersAndTables | superuser|global(A) | |
| moveTables | superuser|global(A) | |
| removeRSGroup | superuser|global(A) | |
| removeServers | superuser|global(A) |
더 알아보기 (Learn more)
HBase 보안과 접근 제어에 대한 자세한 내용은 AccessController 및 HBase 보안 관련 문서를 이어서 보시길 권해요.