MYMONDAY.ai
서비스스튜디오도구데이터·포맷73CSS 생성기19색상·이미지10인코딩·보안10웹·SEO11개발·데브옵스10파일·내보내기18계산기6가이드

7분 읽기 · 마지막 업데이트

chmod 755와 644의 차이: 리눅스 파일 권한 숫자, umask, 특수 권한 정리

유닉스 권한은 열두 개의 비트일 뿐입니다. 이를 8진수 세 자리로 읽을 수 있게 되면 ls -l, chmod, umask는 외울 대상이 아니라 간단한 계산이 됩니다.

세 부류, 아홉 개의 비트

리눅스, macOS, BSD의 모든 파일과 디렉터리에는 POSIX가 정한 권한(mode)이 붙어 있습니다. 읽기, 쓰기, 실행 세 가지 비트가 세 부류에 각각 있습니다. 부류는 소유자(user, u), 소유 그룹(group, g), 나머지 모든 사용자(other, o)입니다. 비트가 모두 아홉 개이고, 뒤에서 다룰 특수 비트가 세 개 더 있습니다.

ls -l은 권한을 열 글자로 보여 줍니다. 첫 글자는 파일 종류이며 -는 일반 파일, d는 디렉터리, l은 심볼릭 링크입니다. 나머지 아홉 글자가 소유자, 그룹, 나머지 순서의 비트이고, 부류마다 r, w, x 또는 권한이 없으면 -로 적습니다.

$ ls -l
-rw-r--r-- 1 alice staff  1204 Oct  1 09:12 notes.txt
-rwxr-x--- 1 alice deploy  310 Oct  1 09:14 release.sh
drwxr-xr-x 2 alice staff  4096 Oct  1 09:10 public

-rw-r--r--   종류 -, 소유자 rw-, 그룹 r--, 나머지 r--   = 644
-rwxr-x---   종류 -, 소유자 rwx, 그룹 r-x, 나머지 ---   = 750
drwxr-xr-x   종류 d, 소유자 rwx, 그룹 r-x, 나머지 r-x   = 755

8진수 계산: 읽기 4, 쓰기 2, 실행 1

권한마다 값이 있습니다. 읽기는 4, 쓰기는 2, 실행은 1입니다. 한 부류가 가진 권한의 값을 더하면 0부터 7까지 숫자 하나가 나옵니다. 4, 2, 1이 2의 거듭제곱이라 합이 겹치지 않으므로, 6은 반드시 4+2, 즉 읽기와 쓰기입니다. 세 부류이니 숫자는 세 자리이고 소유자가 맨 앞입니다.

반대로 읽을 때는 숫자를 자리별로 쪼갭니다. 754라면 소유자 7은 rwx, 그룹 5는 4+1이라 r-x, 나머지 4는 r--이므로 rwxr-xr--입니다. 여덟 가지 숫자는 아래 표에 모두 있습니다.

숫자합2진수기호
0없음000---
11001--x
22010-w-
32+1011-wx
44100r--
54+1101r-x
64+2110rw-
74+2+1111rwx

파일과 디렉터리에서 r, w, x의 뜻이 다르다

일반 파일에서는 이름 그대로입니다. 읽기는 내용을 보는 것, 쓰기는 내용을 바꾸는 것, 실행은 커널이 그 파일을 프로그램으로 실행하는 것입니다. ./deploy.sh처럼 셸 스크립트를 직접 실행하려면 인터프리터가 파일을 읽어야 하므로 읽기와 실행이 모두 필요합니다.

디렉터리에서는 세 비트의 뜻이 달라집니다. 읽기는 안에 든 이름을 나열하는 권한입니다. 실행은 검색(search) 권한이라고도 부르며, 디렉터리를 통과하는 권한입니다. cd로 들어가거나 이름을 알고 있는 항목에 접근하는 것이 여기에 해당합니다. 쓰기는 항목을 만들고, 이름을 바꾸고, 지우는 권한이지만 실행 비트도 함께 있어야 동작합니다. 파일을 지울 수 있는지는 파일 자신의 권한이 아니라 그 파일이 든 디렉터리의 쓰기 비트가 정합니다.

  • r만 있고 x가 없는 디렉터리: ls로 이름은 보이지만 안의 파일을 열거나 정보를 조회할 수 없습니다.
  • x만 있고 r이 없는 디렉터리: 목록은 볼 수 없지만 정확한 이름을 알고 파일이 읽기 가능하면 cat dir/known-name은 동작합니다.
  • 웹 서버나 서비스 계정이 접근하는 경로의 모든 상위 디렉터리에 x가 있어야 합니다. 700 디렉터리 안의 644 파일은 다른 사용자에게는 닿지 않습니다.

실제로 쓰는 권한 조합

가능한 조합은 512가지지만 실무는 몇 가지로 거의 다 해결됩니다. 규칙은 단순합니다. 파일에는 실행 비트가 거의 필요 없고, 디렉터리에는 거의 항상 필요하며, 비밀 파일은 그룹과 나머지 자리를 0으로 만듭니다.

권한기호쓰는 곳
755rwxr-xr-x프로그램, 누구나 실행해도 되는 스크립트, 공개 디렉터리
644rw-r--r--HTML, 소스 코드, 누가 읽어도 되는 설정 같은 일반 파일
600rw-------SSH 개인키, 자격 증명 등 소유자만 다루는 파일
700rwx------~/.ssh 같은 개인 디렉터리
640rw-r-----서비스 그룹은 읽고 그 밖은 막아야 하는 로그 같은 파일
750rwxr-x---소유자와 특정 그룹만 쓰는 프로그램이나 디렉터리
775rwxrwxr-x팀 그룹이 함께 쓰는 공유 디렉터리

심볼릭 모드: 바꾸려는 것만 바꾸기

8진수는 권한 전체를 한 번에 지정합니다. 심볼릭 모드는 비트를 하나씩 고치므로 한 가지만 바꾸고 싶을 때 안전합니다. 문법은 대상(u, g, o, 전체는 a), 연산자(+ 추가, - 제거, = 정확히 지정), 권한(r, w, x, X, s, t)을 이어 쓰는 것이고 여러 절은 쉼표로 잇습니다.

꼭 익혀 둘 것은 대문자 X입니다. 대상이 디렉터리이거나 이미 누군가에게 실행 권한이 있을 때만 실행 비트를 더합니다. 그래서 chmod -R u=rwX,go=rX tree 한 줄이면 디렉터리의 일반 rwx 비트는 755, 실행 비트가 없던 파일은 644가 됩니다. 이미 실행 가능했던 파일은 755가 되고 디렉터리에 있던 setuid나 setgid 비트는 남을 수 있습니다. 따라서 일반 파일에 처음부터 실행 비트가 없고 디렉터리에 지울 특수 비트가 없을 때만 앞의 find 두 줄과 비슷한 결과입니다.

+와 =의 차이도 알아 두세요. chmod g+w file은 비트 하나만 더하고 그룹의 나머지 권한은 그대로 두지만, chmod g=w file은 그룹 권한 전체를 바꿉니다. 그래서 g=만 쓰면 그룹 권한이 모두 지워집니다. 작은 수정에는 +와 -를, 최종 결과를 명시하고 싶을 때는 =를 쓰세요.

명령시작 권한결과
chmod u+x file644744
chmod g-w file664644
chmod o= file755750
chmod a+r file600644
chmod a+x file644755
chmod u=rwx,go=rx file무관755

umask: 기본 권한은 어디서 오는가

새 파일은 666, 새 디렉터리는 777로 생성이 요청되고, 프로세스의 umask가 거기서 비트를 끕니다. 최종 권한은 요청 권한 AND NOT umask입니다. 파일을 777이 아니라 666에서 시작하는 것은 파일이 실수로 실행 가능해지지 않게 하려는 것입니다.

흔한 umask 022는 그룹과 나머지의 쓰기를 지우므로 666은 644, 777은 755가 됩니다. 뺄셈이 아니라 비트 연산으로 계산해야 합니다. umask 033이라면 666은 633이 아니라 644가 됩니다. 요청 권한에 없는 실행 비트는 마스크로 지울 것이 없기 때문입니다.

umask 022   파일 666 -> 644   디렉터리 777 -> 755
umask 002   파일 666 -> 664   디렉터리 777 -> 775
umask 027   파일 666 -> 640   디렉터리 777 -> 750
umask 077   파일 666 -> 600   디렉터리 777 -> 700

setuid, setgid, sticky 비트

맨 앞에 네 번째 8진수 자리를 두면 특수 비트를 지정합니다. setuid는 4, setgid는 2, sticky는 1입니다. ls -l에서는 x 자리를 대신해 나타납니다. 소유자 자리의 s는 setuid, 그룹 자리의 s는 setgid, 나머지 자리의 t는 sticky입니다. 대문자(S, T)는 특수 비트는 켜졌는데 짝이 되는 실행 비트는 꺼졌다는 뜻입니다. 실행 파일의 setuid가 S로 보이면 대개 실수입니다. 디렉터리에서는 해당 부류에 검색 권한이 없어도 다른 부류가 디렉터리를 통과할 수 있다면 S·T가 의도된 설정일 수 있고, 통과할 수 있는 사용자에게 setgid 상속이나 sticky 삭제 제한이 여전히 적용됩니다.

실행 파일에서 setuid는 프로그램이 소유자의 신원으로 실행되게 합니다. passwd가 root 소유인 이유가 이것이고, setgid는 그룹에 대해 같은 일을 합니다. 리눅스 커널은 인터프리터로 실행하는 스크립트의 setuid를 무시하므로, 컴파일된 바이너리에서만 동작합니다. 디렉터리에서 setgid는 새 파일이 디렉터리의 그룹을 물려받게 하는데, 팀 공유 폴더를 만드는 표준적인 방법입니다. 디렉터리의 sticky 비트는 삭제를 제한합니다. 파일 소유자, 디렉터리 소유자, root만 항목을 지울 수 있으며 /tmp가 1777(drwxrwxrwt)인 이유입니다.

권한기호의미
4755rwsr-xr-x소유자 권한으로 실행되는 setuid 프로그램
2755rwxr-sr-x그룹 권한으로 실행되는 setgid 프로그램
2775rwxrwsr-x팀용 setgid 디렉터리, 새 파일이 그룹을 상속
1777rwxrwxrwt/tmp처럼 누구나 쓰되 삭제는 제한되는 sticky 디렉터리
4644rwSr--r--소유자 실행 없이 setuid만 켜진, 실수일 가능성이 높은 조합

chmod 777이 위험 신호인 이유

777이면 모든 로컬 사용자와, 어떤 사용자로든 돌고 있는 침해된 프로세스가 그 파일을 덮어쓸 수 있습니다. 그 파일이 다른 곳에서 실행하는 스크립트라면 임의 코드 실행으로 이어집니다. 디렉터리라면 sticky 비트가 없는 한 누구나 안의 파일을 지우거나 바꿔치기할 수 있습니다.

진짜 원인도 가려집니다. "permission denied"는 거의 세 가지 중 하나입니다. 소유자나 그룹이 틀렸거나(chown으로 해결), 상위 디렉터리에 x가 없거나(그 디렉터리에 chmod +x), SELinux, AppArmor, 읽기 전용 마운트처럼 권한 비트로는 못 뚫는 보안 계층입니다. 여러 사람이 써야 한다면 그룹을 만들고 디렉터리를 그 그룹에 넘긴 뒤 775에 setgid(2775)를 쓰세요.

무심코 친 chmod -R 777 .은 한 가지 점에서 더 해롭습니다. 모든 파일을 실행 가능으로 만들어 스크립트와 데이터의 구분을 지워 버립니다. 원래 권한이 어디에도 기록되지 않아서 권한만으로는 되돌릴 수도 없습니다.

실전: SSH 키, 웹 루트, 배포 스크립트

SSH는 의도적으로 엄격합니다. OpenSSH는 다른 사용자가 읽을 수 있는 개인키를 "Permissions 0644 for key are too open" 같은 메시지와 함께 거부합니다. 개인키는 600(또는 400), ~/.ssh 디렉터리는 700으로 두세요. 공개키는 644여도 됩니다. StrictModes가 켜진 sshd는 홈 디렉터리, ~/.ssh, authorized_keys를 그룹이나 나머지가 쓸 수 있으면 키를 받아 주지 않습니다.

웹 루트는 디렉터리 755, 파일 644로 두고 소유자는 배포 계정으로 하며, 웹 서버는 나머지 사용자 비트로 읽게 합니다. 숫자 모드 하나를 재귀로 적용하면 둘 중 하나는 틀리니 따로 지정하세요. 스크립트는 755(특정 그룹만 실행하게 하려면 750)를 쓰고, git은 실행 비트 여부만 기록한다는 점을 기억해 두세요. 파일은 100644 또는 100755로 저장되며, git update-index --chmod=+x script.sh로 변경을 기록합니다. GNU chmod는 짧은 숫자 모드를 디렉터리에 적용할 때 기존 setuid나 setgid 비트를 보존할 수 있습니다. 그래서 계산기는 디렉터리나 재귀 대상에 00755 같은 다섯 자리 모드를 내고, 심볼릭 명령에는 해당 비트를 꺼야 할 때 u-s,g-s를 명시합니다.

# SSH
chmod 700 ~/.ssh
chmod 600 ~/.ssh/id_ed25519
chmod 644 ~/.ssh/id_ed25519.pub

# 웹 루트: 디렉터리 755, 파일 644
find /var/www/site -type d -exec chmod 00755 {} +
find /var/www/site -type f -exec chmod 644 {} +

# 비슷한 한 줄 결과; 실행 가능 파일과 디렉터리 setuid/setgid는 남을 수 있음
chmod -R u=rwX,go=rX /var/www/site

# 팀 공유 디렉터리
chgrp -R devs /srv/project
chmod -R g+rwX /srv/project
find /srv/project -type d -exec chmod g+s {} +

권한 확인과 디렉터리 점검

파일의 8진수 권한을 바로 보려면 리눅스의 GNU coreutils에서 stat -c '%a %A %n' file을 쓰세요. 644 -rw-r--r-- file 같은 결과가 나옵니다. macOS와 BSD에서는 stat -f '%Lp %Sp %N' file이 같은 역할을 합니다. 손으로 입력한 권한이 맞는지 확인하는 가장 빠른 방법은 숫자와 문자를 나란히 비교하는 것입니다.

디렉터리 트리를 점검할 때는 ls 출력을 눈으로 읽지 말고 find가 권한으로 직접 고르게 하세요. -perm 앞의 대시는 나열한 비트가 모두 켜져 있어야 한다는 뜻이고, 슬래시는 그중 하나라도 켜져 있으면 된다는 뜻입니다.

# 누구나 쓸 수 있는 파일
find /var/www -type f -perm -o+w

# 실행 비트가 하나라도 켜진 일반 파일 (chmod 644 후보)
find /var/www -type f -perm /111

# 실행 비트가 없는 디렉터리 (아무도 들어갈 수 없음)
find /var/www -type d ! -perm -u+x

직접 해보기