본문 바로가기
Infra & DevOps/Linux

[퍼온 글] namespace

by Jordy-torvalds 2020. 6. 4.
반응형

출처: https://galid1.tistory.com/442

Namespace 란?

- 한덩어리의 데이터에 이름을 붙혀 충돌 가능성을 줄이고, 쉽게 참조할 수 있게하는 개념

Linux 커널의 namespace 기능은

** Linux의 오브젝트에 이름을 붙임으로써 다음과 같은 6개의 독립된 환경을 구축할 수 있다.**

1. PID namespace

- 프로세스에 할당된 고유한 ID를 말하며 이를 통해 프로세스를 격리할 수 있다

- namespace가 다른 프로세스 끼리는 서로 액세스할 수 없다

2. Network namespace

- 네트워크 디바이스, IP 주소, Port 번호, 라우팅 테이블, 필터링테이블 등의 네트워크 리소스를 namespace마다 격리시켜

독립적으로 가질 수 있다. 이 기능을 이용하면 OS 상에서 사용중인 Port가 있더라도 컨테이너 안에서 동일한 Port를 사용 가능하다.

3. UID namespace

- UID, GID를 namespace 별로 독립적으로 가질 수 있도록 한다.

- namespace 안과 호스트 OS 상에서 서로 다른 UID, GID를 가질 수 있다.

4. Mount namespace

- 호스트 OS와 namespace가 서로 다른 격리된 파일시스템 트리를 가질 수 있도록 한다

(마운트는 컴퓨터에 연결된 기기나 기억장치를 OS에 인식시켜 사용가능한 상태로 만드는 것을 의미한다)

5. UTS namespace

- namespace 별로 호스트명이나 도메인 명을 독자적으로 가질 수 있다

6. IPC namespace

- 프로세스간 통신(IPC) 오브젝트를 namespace 별로 독립적으로 가질 수 있다


출처: https://tribal1012.tistory.com/268 [Trillion]

 

  Browser sandbox에서 호스트와 자원을 격리하기 위해서 namespace를 사용하고 있다. 따라서 namespace가 무엇이고, 어떤 식으로 격리하고 있는지만 알아보고자 한다.

 

개요

  Linux namespace를 검색해 보면 docker와 같이 자주 나오는 것을 확인할 수 있다. 그 이유는 docker의 container가 Linux Kernel에서 제공하는 namespace를 추상화하여 만들어졌기 때문이다. docker의 container 개념은 가상화의 hypervisor와 자주 비교되는데 참고자료 4번째 link에 간략하게 설명되어 있다.

  Linux의 namespace는 system에서 사용하는 일부 자원들을 분할하고 격리하여 사용하는 기능이다(이 때, system으로부터 격리된 프로세스를 container). Linux에서 현재 지원하는 namespace 항목은 다음과 같다.

  • MNT(Mount) : 파일 시스템 관련
  • UTS(Unix Time sharing) : hostname과 NIS(Network Internet Service) domain name 관련
  • IPC(Inter Process Communication) : 프로세스간 IPC 통신 관련
  • NET(Network) : 네트워크 자원 관련
  • PID(Process ID) : 프로세스 트리 관련
  • USER : 사용자 접근 관련

 

MNT Namespace

  Linux에서는 system에 마운트된 장치에 대해 어떤 장치가 어디에 어떤 권한으로 마운트되었는지에 대한 정보를 구조체의 형태로 저장하고 있다. Mount Namespace는 이 구조체 자체를 복제한 후, 마운트된 위치를 격리하는 것으로 생성된다. 

  chroot는 단순히 root(/)의 경로를 설정해서 제한하는 것으로, 격리가 완전하다고 할 수 없다. 따라서 CWE-243과 같이 경로는 제한했지만, 작업 디렉토리를 통해 상대 경로로 경로 외부에 접근하는 취약점도 존재한다.

  MNT Namespace는 다른 프로세스에 전혀 영향을 끼치지 않고 전혀 다른 마운트 위치를 가질 수 있기 때문에 다양한 용도로 사용할 수 있다.

 

 

UTS Namespace

  system의 hostname을 격리하는데 사용한다. Linux를 설치할 때, hostname을 설정하면 이 정보는 커널이 가지고 있다. uname -n 커맨드를 입력하면 설정했던 hostname을 확인할 수 있는데 네트워크 상에서 특정 system의 host들을 구분하는데 사용된다. 일단 UTS Namespace를 생성하면 아래와 같은 구조체가 복사된다.

1

2

3

4

5

6

7

8

9

10

11

/* /usr/include/linux/utsname.h */

#define __NEW_UTS_LEN 64

    

struct new_utsname {

    char sysname[__NEW_UTS_LEN + 1];

    char nodename[__NEW_UTS_LEN + 1];

    char release[__NEW_UTS_LEN + 1];

    char version[__NEW_UTS_LEN + 1];

    char machine[__NEW_UTS_LEN + 1];

    char domainname[__NEW_UTS_LEN + 1];

};

Colored by Color Scripter

cs

  다른 namespace에 비해 특별해 보이는 기능은 딱히 없고, hostname을 기반으로 동작하는 작업이나 네트워크 상에서 domain name을 변경하는 용도로 사용한다.

 

IPC Namespace

  IPC(Inter-Process Communication)는 프로세스간 통신을 나타내는 용어이다. 프로세스간 통신을 하는 방법에는 여러가지가 있는데, IPC Namespace는 그 중에서 IPC 객체인 message queue(posix), semaphore, shared memory를 격리한다. IPC를 격리하게 되면 통신을 하고 있는 프로세스까지 같이 격리가 되는 것이 아니라 프로세스간 통신하고 있는 통로만을 격리한다.

 

NET Namespace

  system에서 네트워크 통신을 하게 되면 네트워크 패킷은 system에 설치된 각 interface를 통해 들어오게 된다. Interface들은 들어온 패킷을 처리하기 위해 각자의 network stack을 가지고 있다가 패킷이 들어오면 받고, 추가적인 처리를 한다. 

  NET Namespace는 별도의 Interface를 생성한 것처럼 사용된다. NET Namespace를 생성하면 새로운 격리된 Interface가 생성되는데 이 Namespace는 기존의 system이 가지는 loopback과 다른 별도의 loopback을 가지며, 다른 Interface와 충돌나면 곤란하기 때문에 별도의 network stack과 route list, rules, port를 따로 가지고 있다.

 

PID Namespace

  리눅스는 프로세스를 생성할 수 없기 때문에 부팅 시 실행되는 프로세스 중 하나인 init 프로세스를 fork()로 복제한 후, execve()로 덮어써 프로세스를 실행한다. 때문에 init 프로세스를 root 노드로 한 Single Process Tree를 가진다.

  PID Namespace는 현재 프로세스의 pid를 복제해 init의 역할을 수행하는 init-like 프로세스를 생성하는 것으로 생성된다. 따라서 Namespace 내부에서 해당 프로세스는 init의 역할을 수행하기 때문에 pid가 1로 지정되고, 새로운 Single Process Tree 처럼 보이게 된다. 하지만 Namespace 외부에서는 현재 같은 system에서 자원을 공유하면서 복제되었기 때문에 Namespace 내부의 Tree를 확인하는 것이 가능하다. 또한 init를 기준으로 Tree를 보는 것이기 때문에 pid가 1이 아닌 정상적으로 보인다.

  이해가 잘 안 간다면 참고자료의 3번째의 Process  Namespace의 그림을 보면 좋다.

 

USER Namespace

  User Namespace는 하나의 격리된 사용자를 생성하는데 사용된다. 간단하게 임시로 권한을 가진 사용자를 생성할 수 있는 기능이다. 이 기능은 사용자를 생성하거나 setuid 적용, 권한 설정과 달리 Namespace라는 제한된 환경에서 root 권한을 부여하여 내부에서만 자유롭게 다양한 접근을 할 수 있게 한다.

  앞에서 말한 사용자 생성, setuid, 권한 설정은 특정 사용자를 위해 제공하기에는 보안상 위험성이 생길 수 있는데, Namespace는 이러한 system 접근 설정에 영향을 주지 않기 때문에 유용하다.




반응형