사전 격리
개념

격리

gabury1

격리는 한쪽이 하는 일이 다른 쪽에 닿지 못하게 떼어 놓는 것입니다. 떼어 놓는 대상은 자리마다 다릅니다. 프로세스일 수도 있고 시험 하나일 수도 있습니다. 무엇을 무엇으로부터 떼어 놓는지를 말하지 않으면 이 말은 성립하지 않습니다.

상세

큰 배의 밑바닥은 하나로 뚫린 공간이 아닙니다. 여러 칸으로 나뉘어 있습니다. 한 칸에 물이 차도 나머지 칸은 마른 채로 남습니다. 배 전체가 가라앉지 않는 이유가 그 칸막이입니다.

격리는 둘 사이에 경계를 두어 한쪽의 동작과 실패와 상태가 다른 쪽에 보이지도 닿지도 않게 만드는 성질입니다. 여기서 두 가지가 갈라집니다. 보이지 않게 하는 것과 닿지 못하게 하는 것입니다. 앞은 저쪽에 무엇이 있는지 알 수 없게 만드는 것입니다. 뒤는 알더라도 건드리지 못하게 만드는 것입니다.

그래서 격리를 말하려면 세 가지를 밝혀야 합니다. 떼어 놓는 대상이 무엇인지, 무엇으로부터 떼어 놓는지, 그리고 무엇이 경계를 못 넘는지입니다. 셋 중 하나라도 비면 격리라는 말만 남고 내용이 없습니다.

격리는 한 번 세우고 끝나는 것이 아닙니다. 경계는 세운 뒤에도 계속 지켜져야 합니다.

격리에는 정도가 있습니다. 아무것도 못 넘는 상태가 한쪽 끝입니다. 반대쪽 끝은 아무 경계도 없는 상태입니다. 실제 시스템은 대개 그 사이 어딘가에 자리를 잡습니다. 경계를 세울수록 같은 것을 여러 벌 두게 됩니다. 경계를 넘어야 하는 일도 그만큼 비싸집니다.

배경

한 기계 위에 여러 프로그램을 같이 올리면 문제가 생깁니다. 하나가 자원을 다 먹거나 죽거나 남의 데이터를 건드리는 순간 나머지가 같이 무너집니다. 한 사람이 쓰던 시절에는 이것이 문제가 아니었습니다. 여럿이 같은 기계를 나눠 쓰기 시작하면서 문제가 됐습니다.

그래서 필요해진 것이 같이 두되 서로 닿지 못하게 하는 경계입니다. 이 경계는 공짜가 아닙니다. 각자에게 따로 줄 자원이 필요합니다. 경계를 넘어야 하는 일에는 값이 붙습니다. 그 값을 치르고서라도 서로 안 무너지는 쪽을 고르기로 한 것이 격리입니다.

Saltzer 와 Schroeder 는 1975년 글 「The Protection of Information in Computer Systems」에서 완전 격리를 하나의 보호 방식으로 정의해 둡니다. 주체들을 여러 구획으로 나누되 구획 사이에는 정보의 흐름도 제어의 흐름도 일어날 수 없게 만든 보호 체계라고 적습니다. 이 정의가 오늘날 쓰이는 격리의 양 끝 중 한쪽 끝을 이름으로 못 박아 둔 자리입니다.

갈래

무엇을 무엇으로부터 떼어 놓느냐가 축입니다. 이 축 위에서 격리는 네 자리로 갈립니다.

데이터베이스에서 말하는 격리는 이 넷과 별개로 섭니다. 한 트랜잭션이 다른 트랜잭션의 중간 상태를 어디까지 보느냐를 단계로 정한 것입니다. 그 단계 이름과 각각이 무엇을 막는지는 격리 수준 항목이 받습니다.

프로세스 격리

떼어 놓는 대상은 메모리 공간입니다. fork(2) 는 부르는 쪽 프로세스를 복제해 새 프로세스를 만듭니다. 만든 쪽이 부모 프로세스이고 만들어진 쪽이 자식 프로세스입니다. 매뉴얼은 자식과 부모가 서로 분리된 메모리 공간에서 돈다고 적습니다.

fork(2) 시점에는 두 메모리 공간의 내용이 같습니다. 그 뒤가 갈립니다. 한쪽이 하는 메모리 쓰기, mmap(2) 을 통한 파일 매핑, munmap(2) 을 통한 매핑 해제는 다른 쪽에 영향을 주지 않습니다.

sequenceDiagram
    participant 부모
    participant 자식
    부모->>자식: fork 로 새 프로세스를 만듦
    Note over 부모,자식: 이 순간 두 메모리 공간의 내용은 같다
    부모->>부모: 자기 메모리에 씀
    Note over 자식: 자식 쪽 메모리는 바뀌지 않는다

네임스페이스 격리

떼어 놓는 대상은 보이는 자원 목록 자체입니다. 리눅스 매뉴얼은 네임스페이스를 전역 시스템 자원을 추상화로 감싸는 것이라고 적습니다. 그 안의 프로세스에게는 그 전역 자원의 자기만의 격리된 인스턴스가 있는 것처럼 보입니다. 전역 자원에 가한 변경은 같은 네임스페이스에 속한 다른 프로세스에게는 보입니다. 바깥의 프로세스에게는 보이지 않습니다. 매뉴얼은 네임스페이스의 용도 하나로 컨테이너 구현을 듭니다.

갈라 주는 자원의 종류마다 네임스페이스가 따로 있습니다. 마운트 지점, PID(Process ID, 프로세스 식별자) 번호 공간, 네트워크 장치와 포트, 사용자와 그룹 식별자, 호스트 이름, IPC(Inter-Process Communication, 프로세스 간 통신) 자원, cgroup 루트 디렉터리, 부팅 시각과 단조 증가 시계가 각각 자기 네임스페이스를 갖습니다.

PID 네임스페이스가 갈라 주는 것은 프로세스 식별자 번호 공간입니다. 서로 다른 PID 네임스페이스에 있는 프로세스들은 같은 PID 를 가질 수 있습니다. 매뉴얼은 이 성질 덕분에 컨테이너가 안의 프로세스 묶음을 통째로 멈췄다 재개하거나 다른 호스트로 옮길 수 있다고 적습니다. 그렇게 옮겨도 안쪽 프로세스들은 같은 PID 를 그대로 유지합니다.

시험 격리

떼어 놓는 대상은 시험 하나가 남긴 상태입니다. 시험이 파일을 만들거나 디렉터리를 어지럽히면 다음 시험이 그 흔적을 물려받습니다. pytest 공식 문서는 tmp_path 픽스처를 제시합니다. 시험 함수마다 고유한 임시 디렉터리를 준다고 적습니다.

같은 시험 함수를 동시에 여러 번 돌리는 것도 지원합니다. 문서는 그 경우 기준 임시 디렉터리를 동시 실행마다 다르게 설정하라고 적습니다. 기본값으로 pytest 는 마지막 세 번의 실행분 임시 디렉터리를 남겨 둡니다.

사고 대응에서의 격리

떼어 놓는 대상은 이미 침해된 것입니다. NIST(National Institute of Standards and Technology, 미국 국립표준기술연구소)의 사고 대응 권고 문서는 봉쇄를 사고의 확산을 막는 일이라고 적습니다. 봉쇄는 추가 피해를 막을 수 있습니다. 조직의 자원이 감당 못 할 지경이 되는 것도 피할 수 있습니다. 문서는 대부분의 사고가 어떤 형태로든 봉쇄를 필요로 한다고 적습니다.

권고는 봉쇄 동작 일부를 자동으로 수행하게 설정하는 것을 고려하라고 적습니다. 악성코드를 격리 보관하는 것, 침해된 단말을 격리된 교정용 네트워크로 옮기는 것, 감염된 컨테이너의 실행을 중단시키는 것이 예로 들려 있습니다.

flowchart TD
    A["사고 발견"] --> B["봉쇄"]
    B --> C["악성코드를 격리 보관"]
    B --> D["침해 단말을 격리 교정망으로"]
    B --> E["감염 컨테이너 실행 중단"]

예시

unshare(2) 의 CLONE_NEWNS

unshare(2) 는 프로세스가 지금 다른 프로세스들과 공유하고 있는 실행 맥락의 일부를 떼어 내게 해 주는 시스템콜입니다. 무엇을 떼어 낼지는 플래그로 고릅니다.

CLONE_NEWNS 는 마운트 네임스페이스를 떼어 냅니다. 이 플래그를 주면 부르는 프로세스는 자기만의 마운트 네임스페이스 사본을 갖게 됩니다. 그 사본은 다른 어떤 프로세스와도 공유되지 않습니다. 매뉴얼은 이 플래그를 쓰려면 CAP_SYS_ADMIN 능력이 필요하다고 적습니다. 이 플래그를 주면 CLONE_FS 도 자동으로 함께 적용됩니다.

CLONE_FS 는 파일 시스템 속성을 떼어 냅니다. 부르는 프로세스가 루트 디렉터리, 현재 디렉터리, umask 속성을 다른 어떤 프로세스와도 더는 공유하지 않게 됩니다. 루트 디렉터리를 바꾸는 것은 chroot(2) 가, 현재 디렉터리를 바꾸는 것은 chdir(2) 가 합니다.

Chrome 의 사이트 격리

사이트 격리는 Chrome 의 보안 기능입니다. Chromium 프로젝트 문서는 이 기능이 일부 종류의 보안 버그에 대해 추가 보호를 제공한다고 적습니다.

동작은 이렇습니다. 서로 다른 웹사이트에서 온 페이지는 언제나 서로 다른 프로세스에 들어갑니다. 각 프로세스는 그 프로세스가 할 수 있는 일을 제한하는 샌드박스 안에서 돕니다.

여기서 사이트를 무엇으로 세느냐가 값을 가릅니다. 문서는 스킴과 등록된 도메인 이름을 사이트로 봅니다. 공개 접미사는 포함하고, 서브도메인과 포트와 경로는 무시합니다. https://foo.example.com:8080 이라는 출처는 https://example.com 이라는 사이트에 속합니다.

관련 항목

격리를 얻는 수단

샌드박스 · 네임스페이스 · 마운트 네임스페이스 · PID 네임스페이스 · cgroup · 컨테이너 · 컨테이너 런타임 · 가상 머신 · 하이퍼바이저 · KVM · 벌크헤드 · 다중 버전 동시성 제어

격리의 하위 종류

프로세스 격리 · 네임스페이스 격리 · 시험 격리 · 사이트 격리 · 장애 격리 · 봉쇄

격리 경계를 조작하는 시스템콜

시스템콜 · fork · unshare · clone · chroot · chdir · umask · CAP_SYS_ADMIN

트랜잭션 격리를 이루는 개념

데이터베이스 · 트랜잭션 · 격리 수준 · READ COMMITTED · REPEATABLE READ · SERIALIZABLE

격리가 깨지면 드러나는 문제

사이드 채널 · 권한 상승 · 공유 상태

격리와 헷갈리는 이웃

캡슐화 · 최소 권한 · 신뢰 경계 · 주소공간

다른 이름: isolation · isolate