파일 권한 체계
Linux는 모든 파일과 디렉토리에 소유자(owner), 그룹(group), 기타(others) 3계층의 권한을 부여합니다. 각 계층에 읽기(r), 쓰기(w), 실행(x) 3가지 권한이 있어 총 9비트로 접근을 제어합니다.
ls -l 명령어로 파일 권한을 확인할 수 있습니다.
ls -la /opt/my-app/
# drwxr-xr-x 5 deploy deploy 4096 Feb 28 10:00 .
# -rw-r--r-- 1 deploy deploy 1234 Feb 28 10:00 config.yaml
# -rwxr-x--- 1 deploy deploy 5678 Feb 28 10:00 start.sh
# -rw------- 1 deploy deploy 256 Feb 28 10:00 .env
# 권한 문자열 해석:
# -rwxr-x---
# │└┬┘└┬┘└┬┘
# │ │ │ └── others: --- (권한 없음)
# │ │ └───── group: r-x (읽기 + 실행)
# │ └──────── owner: rwx (읽기 + 쓰기 + 실행)
# └────────── 타입: - (일반 파일), d (디렉토리), l (심볼릭 링크)
권한의 숫자 표현(8진수)도 자주 사용합니다.
| 권한 | 문자 | 숫자 | 의미 |
|---|---|---|---|
| 읽기 | r | 4 | 파일 내용 읽기 / 디렉토리 목록 조회 |
| 쓰기 | w | 2 | 파일 수정 / 디렉토리 내 파일 생성·삭제 |
| 실행 | x | 1 | 파일 실행 / 디렉토리 진입(cd) |
예를 들어 755는 소유자(7=4+2+1=rwx), 그룹(5=4+1=r-x), 기타(5=4+1=r-x)를 의미합니다.
chmod — 권한 변경
chmod 명령어로 파일 권한을 변경합니다. 숫자 방식과 기호 방식 두 가지가 있습니다.
# === 숫자 방식 ===
# 644: 소유자 읽기+쓰기, 그룹/기타 읽기 전용
chmod 644 config.yaml
# 755: 소유자 전체, 그룹/기타 읽기+실행
chmod 755 start.sh
# 600: 소유자만 읽기+쓰기 (비밀 파일에 적합)
chmod 600 .env
# === 기호 방식 ===
# u=소유자, g=그룹, o=기타, a=전체
# +추가, -제거, =설정
# 소유자에게 실행 권한 추가
chmod u+x deploy.sh
# 기타 사용자의 읽기 권한 제거
chmod o-r config.yaml
# 그룹에 읽기+쓰기 설정 (기존 권한 대체)
chmod g=rw shared-doc.txt
# 전체 사용자에게 읽기 권한 부여
chmod a+r README.md
# === 디렉토리 재귀 적용 ===
# -R: 하위 파일/디렉토리 모두 적용
chmod -R 755 /opt/my-app/public/
# 파일과 디렉토리를 구분하여 적용 (find 활용)
# 디렉토리: 755 (진입 필요하므로 x 필수)
find /opt/my-app -type d -exec chmod 755 {} \;
# 파일: 644 (실행 불필요)
find /opt/my-app -type f -exec chmod 644 {} \;
디렉토리에는 x 권한이 있어야 cd로 진입할 수 있습니다. 디렉토리에 r 없이 x만 있으면 파일 이름을 알 때만 접근 가능합니다.
chown — 소유자 변경
chown 명령어로 파일의 소유자와 그룹을 변경합니다.
# 소유자 변경
sudo chown deploy config.yaml
# 소유자와 그룹 동시 변경
sudo chown deploy:deploy config.yaml
# 그룹만 변경 (chgrp과 동일)
sudo chown :webteam shared-doc.txt
# 디렉토리 재귀 변경
sudo chown -R deploy:deploy /opt/my-app/
# 심볼릭 링크 자체의 소유자 변경 (-h 옵션)
sudo chown -h deploy:deploy /opt/my-app/current
배포 디렉토리의 권장 소유권 설정입니다.
# 애플리케이션 디렉토리: 배포 사용자 소유
sudo chown -R deploy:deploy /opt/my-app/
# 로그 디렉토리: 앱 사용자 소유, 그룹 읽기 허용
sudo chown -R deploy:adm /var/log/my-app/
sudo chmod -R 750 /var/log/my-app/
# 설정 파일: root 소유, 앱 사용자 읽기만
sudo chown root:deploy /opt/my-app/.env
sudo chmod 640 /opt/my-app/.env
사용자와 그룹 관리
사용자와 그룹을 생성·관리하는 명령어입니다.
# === 사용자 관리 ===
# 사용자 생성 (-m: 홈 디렉토리 생성, -s: 기본 셸)
sudo useradd -m -s /bin/bash deploy
# 비밀번호 설정
sudo passwd deploy
# 사용자 정보 수정 (셸 변경)
sudo usermod -s /bin/zsh deploy
# 사용자를 그룹에 추가 (-aG: 기존 그룹 유지하며 추가)
sudo usermod -aG docker deploy
sudo usermod -aG www-data deploy
# 사용자 삭제 (-r: 홈 디렉토리도 삭제)
sudo userdel -r olduser
# 사용자 정보 확인
id deploy
# uid=1001(deploy) gid=1001(deploy) groups=1001(deploy),999(docker),33(www-data)
# === 그룹 관리 ===
# 그룹 생성
sudo groupadd webteam
# 그룹에 사용자 추가
sudo usermod -aG webteam alice
sudo usermod -aG webteam bob
# 그룹 삭제
sudo groupdel oldgroup
# 현재 사용자의 그룹 확인
groups deploy
# deploy : deploy docker www-data webteam
usermod -aG에서 -a 옵션을 빠뜨리면 기존 그룹이 모두 제거되고 지정한 그룹만 남습니다. 반드시 -aG를 함께 사용하세요.
특수 권한 — setuid, setgid, sticky bit
일반 rwx 외에 3가지 특수 권한이 있습니다.
| 특수 권한 | 숫자 | 효과 |
|---|---|---|
| setuid (s) | 4000 | 파일 실행 시 소유자 권한으로 실행 |
| setgid (s) | 2000 | 파일: 그룹 권한으로 실행 / 디렉토리: 하위 파일이 부모 그룹 상속 |
| sticky bit (t) | 1000 | 디렉토리 내 파일을 소유자만 삭제 가능 |
# setgid 디렉토리 — 팀 공유 폴더에 유용
# 하위에 생성되는 파일이 자동으로 webteam 그룹 소속
sudo mkdir /opt/shared
sudo chown root:webteam /opt/shared
sudo chmod 2775 /opt/shared
# drwxrwsr-x 2 root webteam 4096 Feb 28 10:00 /opt/shared
# sticky bit — /tmp 디렉토리에 기본 적용
ls -ld /tmp
# drwxrwxrwt 10 root root 4096 Feb 28 10:00 /tmp
# 마지막 t가 sticky bit (다른 사용자의 파일 삭제 불가)
sudoers 설정
sudo 명령어의 권한을 제어하는 /etc/sudoers 파일 설정입니다. 직접 편집하지 말고 반드시 visudo를 사용하세요.
# sudoers 편집 (문법 검사 포함)
sudo visudo
# 또는 /etc/sudoers.d/ 디렉토리에 파일 추가 (권장)
sudo visudo -f /etc/sudoers.d/deploy
sudoers 파일 형식입니다.
# /etc/sudoers.d/deploy
# 형식: 사용자 호스트=(실행사용자) 명령어
# deploy 사용자에게 전체 sudo 권한
deploy ALL=(ALL) ALL
# 비밀번호 없이 sudo 사용 (자동화 서버용)
deploy ALL=(ALL) NOPASSWD: ALL
# 특정 명령어만 허용 (보안 강화)
deploy ALL=(ALL) NOPASSWD: /bin/systemctl restart my-app, /bin/systemctl status my-app
# 그룹 단위 설정 (%그룹명)
%webteam ALL=(ALL) NOPASSWD: /usr/bin/docker, /usr/bin/docker-compose
# sudoers 파일 권한 확인 (반드시 440이어야 함)
ls -l /etc/sudoers
# -r--r----- 1 root root 755 Feb 28 10:00 /etc/sudoers
# sudo 권한 확인
sudo -l -U deploy
# User deploy may run the following commands:
# (ALL) NOPASSWD: /bin/systemctl restart my-app
# (ALL) NOPASSWD: /bin/systemctl status my-app
실전 팁
- 최소 권한 원칙: 파일에는 필요한 최소한의 권한만 부여하세요. 특히
.env, 인증서 키 파일은600(소유자만 읽기+쓰기)으로 설정합니다. - 777 사용 금지:
chmod 777은 모든 사용자에게 모든 권한을 부여합니다. 보안 감사에서 즉시 지적되는 항목입니다. 문제가 생기면 정확한 원인을 파악하여 필요한 권한만 부여하세요. - umask 설정: 새 파일 생성 시 기본 권한을 결정합니다.
umask 022(기본)이면 파일은 644, 디렉토리는 755로 생성됩니다. 보안이 중요한 서버에서는umask 027로 기타 사용자의 접근을 차단하세요. - ACL(Access Control List): 기본 rwx로 부족할 때
setfacl/getfacl명령어로 세밀한 권한 제어가 가능합니다. 예를 들어 특정 사용자에게만 읽기 권한을 추가할 수 있습니다. - sudoers.d 디렉토리 활용:
/etc/sudoers를 직접 편집하지 말고/etc/sudoers.d/디렉토리에 파일별로 관리하면 설정 충돌을 방지하고 자동화 도구(Ansible 등)와 연동하기 편리합니다.