다중 사용자 시스템 Multi-User system ?

 우리가 리눅스를 사용할 때 가장 먼저 하는 일은 로그인(login)이다. 이 과정을 통해 사용자의 홈 디렉토리에서 셸(Bash 등)이 기동되어 허가된 파일을 읽고 쓰고 실행하는 것이 가능해진다. 로그인이 필요한 이유는 여러 명의 사용자가 동시에 사용할 수 있게 만들기 위함이다. 이런 시스템을 다중 사용자 시스템(multi-user system)이라고 한다. 다중 사용자 시스템이 아닌 운영체제도 있다. iOS나 안드로이드(Android)가 그렇다. 그렇다면 왜 여러 명의 사용자가 필요할까?

 

 

 

권한의 분할

 시스템에는 libc.so.6과 같이 중요한 파일도 있고, 임시 메모 파일처럼 시스템 관점에서는 중요하지 않은 파일도 있다. 이 두 파일은 중요도가 다르다. 따라서 시스템에 있어 중요한 파일은 보통의 사용자와 구별된 별도의 사용자가 소유하도록 하고, 해당 소유자 이외에는 수정/삭제가 불가능하도록 만드는 것이다. 이런 일을 하기 위해 사용자별 파일에 대한 권한(permission)이 적용된다. 그래서 사용자별로 읽기/쓰기/실행 가능한 파일이 다르게 되는 것이다.

 

 

 

그룹 Group

 그룹을 사용하면 권한을 더 유연하게 배정할 수 있다. 가령, DVD 드라이브를 사용하도록 허가하고 싶은 사용자가 있고 그렇지 않은 사용자가 있다고 하자. 그럴 때 허가할 사용자들을 dvd 그룹에 묶고, 그 그룹에 DVD 드라이브(디바이스 파일 /dev/sr() 등)에 대한 읽기/쓰기 권한을 부여하면 된다.

 각 사용자는 항상 최소한 한 개의 그룹에 소속되어 있다. 보통 이 최초의 그룹을 기본 그룹이라고 하는데, useradd 명령어로 사용자를 만들 때 -g 옵션을 주어 지정하는 것이 가능하다. 그리고 시스템 관리자는 하나의 사용자를 기본 그룹 이외에 여러 그룹에 한꺼번에 추가하는 것이 가능하다. 사용자를 만들 때 useradd 명령어에 -G 옵션으로 지정하거나 만들어진 사용자에 대해 vigr 명령어를 사용하여 추가할 수 있다. 이렇게 기본 그룹 이외에 추가로 가지는 그룹을 부가 그룹(supplementary groups)이라 한다.

 

 

 

권한 Permission

 권한은 다음 세 집단에 대해 서로 다른 권한 설정이 가능하다.

- 파일을 소유하는 사용자

- 파일을 소유하는 그룹에 속한 사용자

- 그 외의 사용자

 그리고 권한의 종류는 세 가지이다.

- 읽을 수 있는 권한(read, r)

- 쓸 수 있는 권한(write, w)

- 실행(execute, x)

  소유 사용자 소유 그룹 그 외
  읽기 쓰기 실행 읽기 쓰기 실행 읽기 쓰기 실행
가능 r w x r w x r w x
불가능 - - - - - - - - -

예를 들어 보자.

rw-r--r-- 의 경우, 소유자만 읽고 쓸 수 있고 나머지는 읽을 수만 있다. 일반적으로 자주 적용되는 권한 설정이다.

rwxr-xr-x 의 경우, 소유자는 읽고 쓰고 실행도 할 수 있고 나머지는 읽고 실행만 할 수 있다. 프로그램이나 디렉토리에 사용되는 패턴이다.

rw------- 의 경우, 소유자만 읽고 쓸 수 있다. SSH의 비밀 키, 본인 이외 사용자가 봐서는 안 될 파일에 적용되는 패턴이다.

권한의 8진수 표기법

 권한을 표현하는 방법에는 다른 방법도 있는데, 그 중 대표적인 것으로 8진수 표기법이 있다. r=4, w=2, x=1, -=0 으로 간주하여 합계를 구하는 것이다. 그려면 "rwx" 의 경우, 4+2+1=7, "r-x" 의 경우, 4+0+1=5 가 된다. 이 값을 세 개 나열한 것이 최종적인 표기에 해당된다. 예를 들어 rwxr-xr-x 면 755, rw-r--r-- 면 644 이다.

 이러한 표기는 비트 연산을 기반으로 한다. r 이 4 인 것은 2진 표기로 100, w가 2인 것은 2진 표기로 010, x가 1인 것은 2진 표기로 001 이기 때문이다. 이러한 표기법은 C 언어에서 그대로 활용하기 쉽다.

디렉토리 권한

디렉토리의 권한은 일반 파일과 조금 다르게 적용된다.

읽기 권한이 있을 시 ls 명령어 등으로 디렉토리의 파일 목록을 확인할 수 있다.
쓰기 권한이 있을 시 그 안에 새로운 파일을 쓰거나 삭제할 수 있다.
실행 가능 권한이 있을 시 그 안에 파일에 접근할 수 있다.

 

 

 

 

 

자격 증명 Credential

 '사용자 A가 특정 파일에 접근한다'는 것은 '사용자 A의 속성을 가진 프로세스가 접근한다'는 뜻이다. 리눅스상에서 활동하는 주체는 사람이 아니라 프로세스이기 때문이다. 그래서 사용자 A가 조작한다는 것은 사용자 A의 속성을 가진 프로세스군이 조작한다는 것과 같은 말이다.

 그런데 여기서 '사용자 A의 속성'이라는 것을 바로 자격 증명(credential)이라고 한다. 자격 증명이란, '이 프로세스는 리눅스상에서 이 사용자의 대리인으로 동작하고 있다'는 증명서다. 커널은 그 증명서를 보고 '이 프로세스는 이 사용자의 파일을 봐도 괜찮구나'라고 판단한다. 거꾸로 말하면, 증명서만 있으면 누가 생성한 프로세스라도 커널은 그 사용자의 대리인으로 인정한다는 말이기도 하다.

 이런 증명서는, 로그인(login)하는 과정에서 사용자의 증명서를 가진 프로세스가 시스템상에 생성된다. 이 최초의 프로세스가 다른 명령(프로세스)를 실행할 때 증명서를 자동으로 복사하고 전달하므로 우리가 로그인해서 생성한 프로세스는 모두 사용자의 대리인 자격을 가지고 실행되는 것이다.

 

 

 

 

 

사용자 이름과 사용자 ID

 우리는 로그인할 때 사용자 '이름'을 입력하지만, 리눅스 커널은 이 사용자 이름을 기반으로 동작하지 않는다. 대신에 사용자 이름에 대응하는 사용자 ID(숫자)를 기반으로 동작한다. 파일의 소유자도 사용자 ID로 기록되며, 프로세스의 자격 증명서도 ID를 기반으로 다뤄진다.

 'ls -l'를 하면 파일의 소유자 이름이 출력되는데, 이는 ls 명령어가 매번 ID를 이름으로 변환하는 것에 불과하다. ls 외에도 사용자 이름을 입력하거나 표시하는 프로그램들은 모두 내부적으로 사용자 ID와 사용자 이름을 변환하여 사용하고 있다.

 

 

 

 

 

사용자 데이터 베이스

 그렇다면 사용자 ID의 매핑은 어디에 기록되어 있을까? 일반적으로는 /etc/passwd에 작성되어 있다.

/etc/passwd 파일 내용 세부사항
구분자 첫 번째 항목 두 번째 항목 세 번째 항목 네 번째 항목
콜론(:) 사용자 이름 x이면 비밀번호가 /etc/shadow 파일에 저장되어 있다는 뜻 사용자 ID 속한 그룹의 ID

 /etc/passwd에는 한 줄 단위로 사용자 정보가 등록되어 있다. 각 줄은 콜론(:)으로 항목이 구분되어 있는데 첫 번째 항목은 사용자 이름이고, 두 번째 항목이 x이면 비밀번호가 /etc/shadow파일에 저장되었음을 의미한다. 그리고 세 번째 항목이 사용자 ID를 나타낸다. 즉, 위 예에서 daemon 사용자의 ID는 1, bin 사용자의 ID는 2인 것이다.

 또 네 번째 항목은 사용자가 속한 그룹의 그룹 ID다. 즉 daemon 사용자는 그룹 ID가 1인 그룹에 소속되었고, bin 사용자는 그룹 ID가 2인 그룹에 소속되어 있다.

 그러나 그룹 ID가 1이라고 하면 어떤 그룹인지 알기 어렵다. 그룹 ID와 그룹 이름의 매핑은 어디에 있을까? 해당 정보는 /etc/passwd와 비슷한 형식으로 /etc/group이라는 파일에 기록되어 있다.

/etc/group 파일 내용 세부사항
구분자 첫 번째 항목 두 번째 항목 세 번째 항목 네 번째 항목
콜론(:) 그룹 이름 - 그룹 ID 부가 그룹인 사용자

 콜론(:)을 구분자로 첫 번째 항목이 그룹 이름이고 세 번째 항목이 그룹 ID다. 따라서 그룹 ID가 1인 그룹은 daemon 그룹이다. 그리고 /etc/group의 네 번째 항목에는 이 그룹이 부가 그룹인 사용자가 기록되어 있다. 위 예에서는 syslog 와 embedded가 부가 그룹으로 adm에 속하는 사용자임을 알 수 있다. (참고로 embedded는 현재 내가 대학 강좌로 듣고 있는 시스템 프로그래밍 강좌의 교수님이 강좌를 위해 생성하신 그룹이며, sys32197330 은 내 학번이다)

 

그러나 만드는 프로그램에서  사용자 이름과 사용자 ID를 다루기 위해 직접 /etc/passwd나 /etc/group을 해석할 필요는 없다. 그리고 보안상으로도 그렇게 해서는 안된다. 대신에 /etc/passwd나 /etc/group에 엑세스하기 위한 전용 API가 있으므로 그것을 사용하면 된다.

+ Recent posts