본문 바로가기
프로그래밍/리눅스

리눅스(Linux) 소유권과 권한

by bantomak 2025. 1. 28.
반응형

소유권(Ownership)과 권한(Permission)

리눅스에서 파일이 생성되면 루트 디렉터리 아래 어딘가에 존재하게 된다. 그런데 리눅스는 여러 사용자의 수많은 파일이 루트 디렉터리에서 시작된 하나의 트리 안에 혼재되어 있다. 파일의 위치나 디렉터리 이름 같은 정보로는 파일의 소유자를 판단할 수 없다. 그래서 리눅스의 모든 파일에는 소유권이 설정되어 있다.

파일 소유권이란

소유권(ownership)은 파일이 사용자의 소유임을 나타내는 속성이다. 파일이 생성되는 순간 파일을 생성한 사용자(user)와 그룹이 소유권을 가지도록 설정된다. '내 파일'도 있지만 '우리 파일'도 있다는 뜻이다.

 

파일 소유권은 ls 명령어를 통해서 확인할 수 있다.

$ ls -l

출력된 내용 중에서 살펴볼 부분은 세 번째와 네 번째 필드에 위치한 파일의 소유자(user)소유 그룹(user group)이다. 

파일 소유권 변경하기

파일의 소유자와 소유 그룹을 변경할 수 있다. 파일의 소유권은 chown 명령어로 변경이 가능하다.

$ chown [option] username[:group] filename

사용자 부분은 파일의 소유자로 설정할 사용자 이름을 입력한다. 소유 그룹도 변경하고 싶으면 사용자 이름 뒤에 :을 붙이고 사용자 그룹 이름을 입력한다. 변경하지 않을 때는 생략하면 된다. 파일 부분에는 소유권을 변경할 파일 이름을 입력한다. 여러 파일을 한꺼번에 변경하고 싶을 때는 파일 이름을 공백(한 칸 띄어쓰기)으로 구분해 입력한다.

  • -R (--recursive) : 지정한 디렉터리와 그 하위 항목의 소유권을 모두 변경한다.
  • -v (--verbose) : 변경된 파일과 디렉터리 정보를 출력한다.
  • -c (--changes) : 실제 변경된 항목만 출력한다.

실제로 파일의 소유권을 변경해 보자.

$ echo "hello, world" > normal_file
$ ls -l normal_file
$ chown horse normal_file
$ sudo chown horse normal_file
$ ls -l normal_file

사용자는 변경되었지만 소유 그룹은 그대로인걸 알 수 있다. 이제 소유 그룹도 변경해 보자.

$ sudo chown horse:animals normal_file
$ ls -l normal_file

파일 권한(Permission)

파일의 소유 여부에 따라 파일 권한을 다르게 설정할 수 있다. 파일 권한(permission)은 해당 파일에 어떤 행위를 할 수 있는지를 정의한 것으로 다음과 같이 나뉜다.

  • 읽기(Write)
  • 쓰기(Read)
  • 실행(Execute)

파일마다 권한을 조합해 설정할 수 있다. 어떤 파일은 읽기, 쓰기, 실행 모두 가능하게, 다른 파일은 읽기만 허용할 수도 있다.

한 파일에 설정한 권한을 모든 사용자에게 동일하게 적용한다면 멀티 유저 시스템인 리눅스에서는 여러 보안 문제가 발생할 수 있다. 그래서 리눅스에서는 파일 권한을 파일의 소유자(user), 소유 그룹(group), 일반 사용자(other) 별로 따로 설정한다.

첫 번째 칼럼에서 디렉터리를 나타내는 d를 제외하고, rwx로 시작하는 부분이 파일 권한을 나타낸다. 파일 권한은 3글자로 구성되며, 순서대로 읽기(r), 쓰기(w), 실행(x) 권한을 나타낸다. 권한이 있으면 해당하는 영문자를 표시하고, 권한이 없으면 하이픈(-)으로 표시한다.

파일 권한 변경하기

파일 권한은 chmod 명령어로 변경한다. 자주 사용하는 옵션에는 소유권을 변경하는 chown 명령어와 유사하다.

$ chmod [option] [file]
  • -R (--recursive) : 지정한 디렉터리와 그 하위 항목의 소유권을 모두 변경한다.
  • -v (--verbose) : 변경된 파일과 디렉터리 정보를 출력한다.
  • -c (--changes) : 실제 변경된 항목만 출력한다.

권한을 설정하는 방법은 두 가지가 있다. 우선 8진수로 입력하는 방법에 대해서 알아보자.

 

8진수 표기법 사용하기

8진수 표기법을 소유자/소유 그룹/일반사용자에게 각각 설정할 수 있다. 파일 권한이 9진수 표기법에 따라 어떻게 표시되는지 예를 들면 다음과 같다.

  • 644 rw-r--r-- : 소유자에게 읽기/쓰기 권한이 있고, 소유 그룹과 일반 사용자는 읽기 권한만 있음
  • 400 r-------- : 소유자만 읽기 권한이 있고 나머지는 아무 권한도 없음
  • 777 rwxrwxrwx : 소유자/소유 그룹/일반 사용자 모두 읽기/쓰기/실행 권한이 있음
  • 755 rwxr-xr-x : 소유자는 모든 권한이 있고, 소유 그룹과 일반 사용자는 읽기/쓰기 권한만 있음

8진수 표기법으로 파일 권한을 변경해 보자.

$ chmod 777 greetings
$ ls -l
$ chmod 644 greetings
$ ls -l
$ chmod 000 greetings
$ ls -l
$ cat greetings

의미 표기법(Symblic Mode) 사용하기

3가지 정보를 한 번에 표기해야 완벽한 의미 표기법이 된다. 단, 누구에게 주는지 생략하면 a로 해석한다.

  • g+w : 소유 그룹에 쓰기 권한 추가
  • a-x : 모든 사용자에게서 실행 권한 제거
  • ug=rx : 소유자와 소유 그룹의 권한을 읽기/실행으로 설정
$ ls -l greetings
$ chmod a+w greetings

$ ls -l greetings
$ chmod a-w greetings
$ ls -l greetings
$ chmod ug=rw greetings
$ ls -l greetings
$ chmod g-w greetings
$ ls -l greetings

읽기 권한

$ cd ~
$ cd /tmp
$ sudo mkdir playground/
$ ls -l

$ sudo chmod 777 playgorund
$ ls -l

horse 사용자로 변경해서 새로운 파일을 만들어보자.

$ su - horse
$ cd /tmp/playground
$ echo "hello my friends" > msg_from_horse
$ ls -l msg_from_horse

pig 사용자로 변경해서 새로 만든 파일의 내용을 읽어보자.

$ su - pig
$ cd /tmp/playground
$ ls -al
$ cat msg_from_horse

다른 사용자가 만든 파일인데 어떻게 조회가 가능한 걸까요? pig 사용자가 msg_from_horse 파일에 대한 읽기 권한이 있기 때문이다. horse와 같은 그룹이기 때문에 그룹에 대한 읽기 권한을 사용한다. 만약 다른 그룹인 apple 사용자였다면 일반 사용자 권한을 사용해서 해당 파일을 읽었을 것이다.

 

쓰기 권한

같은 그룹에 속한 다른 사용자들이 해당 파일을 수정하기 위해서는 읽기 권한이 필요하다. 아래처럼 소유 그룹에 대한 읽기 권한을 추가하면 horse와 같은 소유 그룹인 pig 사용자에서도 msg_from_horse 파일을 수정할 수 있다.

$ chmod g+w msg_from_horse
$ ls -l msg_from_horse

$ echo "hey~" > msg_from_horse
$ cat msg_from_horse

 

실행 권한

파일을 실행하려면 사용자가 해당 파일에 대한 실행 권한이 있어야 한다. 읽기/쓰기 권한과 마찬가지로 실행하려는 사용자와 파일 소유자의 관계에 따라 실행 권한 검사를 하게 된다. 여기서 종종 놓치는 부분이 있는데, 파일 소유자도 파일을 실행하려면 실행 권한

이 있어야 한다는 점이다. 일반적으로 nano, vim, touch, echo 같은 명령어로 파일을 생성하면 실행권한이 없는 상태로 생성된다.

(파일명 앞에 ./를 붙여서 해당 파일을 실행할 수 있다.)

$ ls -al
$ ./msg_from_horse

실행해 보면 실행 권한이 없어서 실행에 실패한다. horse 사용자가 만든 파일이지만 실행권한이 없기 때문이다.

chmod u+x 명령어를 통해서 소유한 유저에게 실행 권한을 부여하자.

$ chmod u+x msg_from_horse
$ ls -l msg_from_horse

다시 실행했지만 hey~라는 해당 명령어를 찾을 수 없다면서 실패한다. 셸에서 파일을 실행하면 시스템이 알아서 파일 형식에 맞춰 실행한다. msg_from_horse 파일은 'hey~'라는 일반 텍스트를 저장해 놓은 파일이다. 리눅스는 일반 텍스트로 작성된 파일의 내용을 명령어로 인식해 실행한다. 예를 들어 ls -al이라는 텍스트가 저장된 파일을 실행하면 실제로는 ls -al이 실행되는 식이다.

직접 셸 스크립트를 작성해서 확인해 보자. 리다이렉션을 이용해서 exec_test 파일을 생성했다. > 는 화면에 출력될 내용을 파일에 쓰라는 의미인데, 기존에 없는 파일이라면 생성하고 기존에 존재하는 파일이라면 덮어쓰기를 한다. >>는 기존 파일 내용 끝에다가 내용을 덧붙이는 역할을 한다. cat 명령어로 exec_test를 확인하면 결과를 알 수 있다.

$ echo "pwd" > exec_test
$ echo "whoami" >> exec_test
$ echo "ls -al" >> exec_test
$ cat exec_teset

이제 다시 exec_test에도 실행 권한을 추가해 주자.

$ chmod u+x exec_test
$ ls -l exec_test
$ ./exec_test

이제 정상적으로 명령어들이 실행되어서 표시되는 걸 확인할 수 있다.

디렉터리 권한

디렉터리 권한은 일반 파일의 권한과는 의미가 조금 다르다. 디렉터리의 읽기 권한은 해당 디렉터리에 있는 파일 목록을 읽을 수 있는 권한이다. 실행 권한은 해당 디렉터리에 들어가 디렉터리 안에 있는 파일에 접근할 수 있는 권한이다. 쓰기 권한은 그 자체만으로는 의미가 없고, 실행 권한이 있어야 의미가 있다.

  • rwx : 파일 목록 조회, 파일 생성/실행/변경/삭제 등 모두 가능
  • r-x : 파일 목록 조회와 파일 실행은 가능하나 파일 생성/변경/삭제는 불가능
  • --- : 파일 목록 조회조차 불가능하고, 디렉터리 진입도 불가능

루트 디렉터리에 있는 /etc 디렉터리는 시스템 설정 파일들이 저장된 디렉터리이다. 소유자와 소유자 그룹 모두 root이고, root를 제외한 사용자는 모두 일반 사용자로 분류된다. /etc 디렉터리에서 일반 사용자의 권한은 r-x이다. 디렉터리 진입, 파일 조회/실행 등은 가능하지만 파일을 변경할 수 없다. 시스템 설정 파일에 알맞은 권한이다.

 

공유 디렉터리로 설정하기

디렉터리 권한에 대해서 어떻게 설정이 되는지 실습해 보자.

$ pwd
$ mkdir test_with_pig
$ ls -l
$ echo "echo hello i am king" > test_with_pig/message
$ cat test_with_pig/message

$ ls -l test_with_pig/
$ ./test_with_pig/message

이 상태에서 잠깐 멈춰서 생각해 보자. 다른 사용자의 셸에서 test_with_pig 디렉터리의 파일 목록을 조회할 수 있을까? 또한 message 파일의 내용을 조회하고 실행할 수 있을까? 어떤 결과가 나오는지 확인해 보자.

새로운 터미널에서 apple 사용자로 home 디렉터리를 확인해 보니 /home/horse 디렉터리 진입에 실패한다.

해당 디렉터리에 진입이 가능하도록 권한을 변경해 보자.

$ whoami
$ chmod o+rx /home/horse
$ ls -l /home/horse

이제 /home/horse 디렉터리에 진입이 가능하다. 그리고 message 파일에 까지 읽기/실행이 가능해졌다.

이번에는 파일 내용을 변경해보려고 한다. 하지만 역시나 파일 권한에 막혀서 거부당한다. 그렇다면 새로운 파일을 만드는 것은 어떨까? 역시나 디렉터리에 쓰기 권한이 없어서 실패한다.

$ echo "echo edit file" > message
$ echo "echo edit file" > reply

우선 해당 디렉터리에 쓰기 권한만 부여해 보도록 하자. 그리면 이제 해당 폴더에 새로운 파일을 만드는 것이 가능해진다.

$ chmod o+w test_with_pig
$ ls -l test_with_pig

위에서 실패했던 명령어를 다시 실행해 보자. 이제 정상적으로 reply 파일이 생성된 것을 확인할 수 있다.

$ echo "echo edit file" > reply

$ mv message lie
$ ls -l
$ ./lie

파일 내용을 변경하는 작업은 파일 권한이 적용되지만, 파일 이름을 변경하는 것은 디렉터리 권한이 적용된다. 이처럼 디렉터리 권한을 적절히 설정하지 않으면 의도치 않은 상황과 맞닥뜨릴 수 있다.

 

비밀 디렉터리로 설정하기

이번에는 파일 이름조차 공유하고 싶지 않은 디렉터리를 만들어보자.

$ chmod o-rx /home/horse
$ ls -al

이제 secret_dir이라는 디렉터리를 만들어보자. secret_dir은 아무에게도 공개하고 싶지 않은 디렉터리이다. 소유자에게만 rwx 권한을 주고, 소유 그룹과 일반 사용자는 아무 권한이 없게 설정하자.

$ pwd
$ mkdir secret_dir
$ chmod go= secret_dir
$ ls -l

해당 디렉터리 안에 비밀 일기를 써놨다. 이제 아무도 이 파일에는 접근 못할 것이다.

$ echo "i love pid" > secret_dir/diary
$ cat secret_dir/diary

$ whoami
$ ls -al /home/horse
$ ls -al /home/horse/secret_diary
$ cat /home/horse/secret_diary

디렉터리의 경로와 파일의 위치를 알고 있더라도 시스템에서 조회조차 할 수 없다. 또한 diary 파일의 이름과 경로를 정확히 알고 있어도 조회가 불가능하다. 하지만 root 계정이라면 어떨까? 

$ su
$ cat /home/horse/secret_dir/diary

horse 사용자가 secret_dir 디렉터리에 설정한 권한이 root 사용자에게는 전혀 적용되지 않는다. 이를 보면 파일과 디렉터리 권한 설정만으로 데이터를 완벽하게 보호할 수 없다는 점을 알 수 있다. root 사용자의 비밀번호가 악의적인 사용자에게 넘어가면 시스템의 모든 데이터는 해당 사용자의 손아귀에 있게 된다. 그래서 비밀번호 관리가 중요하고, 중요한 데이터는 암호화해서 보호해야 한다.

함께 읽으면 좋은 글

 

File Permissions and Access Control Lists

Linux is a multi-user operating system, so more than one person can work on the same computer at the same time. What’s great, the system can be accessed locally or remotely. That’s why developers often use this OS for group projects. In such a large ..

arnavdevops.hashnode.dev

댓글