파일 · 권한 · 사용자 관리 06 / 50 · Part 1. Linux 파일 관리 기초
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 11. Linux 파일과 디렉터리 관리 · 12. 절대경로와 상대경로

1. 들어가며

cd는 너무 단순해 보여서 따로 공부할 대상이 아닌 것 같다. 하지만 cd에는 Linux 프로세스와 권한 모델의 핵심이 두 가지 들어 있다.

  1. 현재 작업 디렉터리(cwd)는 프로세스의 속성이다. 그래서 cd는 외부 프로그램일 수 없고 쉘 내장 명령(builtin)이어야 한다.
  2. 디렉터리에 들어가는 권한은 r이 아니라 x다. 소유자 본인이라도 x가 없으면 들어갈 수 없다.

이번 글에서는 cd의 주요 사용법과 함께 이 두 원리를 실습으로 확인한다.


2. 핵심 개념

2-1. cd 사용법

형태이동 위치해석 주체
cd홈 디렉터리 ($HOME)쉘
cd ~ / cd ~analyst내 홈 / 지정 사용자 홈쉘
cd -직전 디렉터리 ($OLDPWD), 이동 후 경로 출력쉘
cd ..상위 디렉터리커널 (.. 엔트리)
cd /var/log절대경로커널
cd -P link심볼릭 링크를 풀어 물리 경로로 이동쉘 + 커널

2-2. 쉘이 관리하는 변수

변수의미
PWD현재 디렉터리 (논리 경로)
OLDPWD직전 디렉터리
HOMEcd만 입력했을 때의 목적지
CDPATH상대경로 cd 시 먼저 찾아보는 디렉터리 목록

3. 동작 원리

cd 는 왜 쉘 내장 명령인가 — chdir() 과 디렉터리 x 권한

3-1. cd가 builtin인 이유

외부 명령은 쉘이 fork()로 자식 프로세스를 만들고 그 안에서 실행한다. 자식이 chdir()로 cwd를 바꿔도 자식이 끝나면 그 상태는 사라진다. 부모 쉘의 cwd는 그대로다. 그래서 쉘 자신이 chdir()을 호출해야 하므로 cd는 builtin 이다. 같은 이유로 export, umask, exit도 builtin이다.

참고로 Rocky 등 일부 배포판에는 /usr/bin/cd라는 파일이 있다. 이것은 POSIX 호환을 위한 스크립트로, 실행해도 호출한 쉘의 위치는 바뀌지 않는다.

3-2. chdir()의 권한 검사

chdir() 시스템 콜은 경로상의 모든 디렉터리와 목적지 디렉터리에 대해 x(search) 권한 을 검사한다. r은 "이름 목록을 읽는 권한"이고, x는 "안으로 들어가거나 통과하는 권한"이다. 둘은 독립적이다.

  • r 없이 x만 있으면 → 들어갈 수는 있지만 ls는 실패한다.
  • x 없이 r만 있으면 → 들어갈 수 없다. 소유자라도 마찬가지다.

4. 명령어 실습

# 1) 기본 이동과 직전 디렉터리
cd /var/log && pwd
cd -                               # 직전 위치로 이동 후 경로 출력
cd ~ && pwd
echo "PWD=$PWD OLDPWD=$OLDPWD"

# 2) x 권한이 없는 디렉터리 (소유자 본인)
mkdir -p ~/lab06/secret && chmod 600 ~/lab06/secret
cd ~/lab06/secret                  # rw- 이지만 x 없음
ls -ld ~/lab06/secret
chmod 700 ~/lab06/secret && cd ~/lab06/secret && pwd

# 3) 다른 사용자(root)의 홈
cd /root
ls -ld /root

5. 실행 결과

실제 실행 결과 — Rocky Linux 9.8 · analyst@rocky9-lab — cd 와 디렉터리 x 권한

텍스트 원본(실제 출력):

[analyst@rocky9-lab ~]$ cd /var/log && pwd
/var/log
[analyst@rocky9-lab log]$ cd - 
/home/analyst
[analyst@rocky9-lab ~]$ cd ~ && pwd
/home/analyst
[analyst@rocky9-lab ~]$ echo "PWD=$PWD OLDPWD=$OLDPWD"
PWD=/home/analyst OLDPWD=/home/analyst
[analyst@rocky9-lab ~]$ mkdir -p ~/lab06/secret && chmod 600 ~/lab06/secret
[analyst@rocky9-lab ~]$ cd ~/lab06/secret
-bash: cd: /home/analyst/lab06/secret: Permission denied
[analyst@rocky9-lab ~]$ ls -ld ~/lab06/secret
drw------- 2 analyst analyst 4096 Sep 24 10:16 /home/analyst/lab06/secret
[analyst@rocky9-lab ~]$ chmod 700 ~/lab06/secret && cd ~/lab06/secret && pwd
/home/analyst/lab06/secret
[analyst@rocky9-lab secret]$ cd /root
-bash: cd: /root: Permission denied
[analyst@rocky9-lab secret]$ ls -ld /root
dr-xr-x--- 1 root root 4096 Sep 24 10:12 /root

6. 결과 해석

출력해석
cd - → /home/analystcd -는 이동과 함께 도착 경로를 출력한다
PWD=/home/analyst OLDPWD=/home/analystcd ~를 홈에서 실행했으므로 직전 위치도 홈이다
cd: .../secret: Permission denied소유자 analyst 본인이 만든 디렉터리지만 권한이 rw-(600)라 x가 없다
drw------- analyst analyst소유자 칸에 r, w는 있지만 x가 없다
chmod 700 후 이동 성공x가 추가되자 들어갈 수 있다
cd: /root: Permission denied/root는 dr-xr-x--- root root. analyst는 other 칸(---)에 해당해 x가 없다

600 디렉터리 실습은 "디렉터리를 파일처럼 600으로 잠그면 안전하다"는 오해를 깨 준다. 디렉터리를 소유자 전용으로 만들 때는 700을 쓴다.


7. 보안 관점

주제내용
경로 통과 권한민감한 파일을 보호하려면 상위 디렉터리의 other x를 제거 하는 것이 가장 확실하다. Rocky의 홈 700, Ubuntu의 홈 750이 그 예다
--x 디렉터리목록은 숨기고 이름을 아는 사람만 접근하게 한다. 하지만 이름을 추측할 수 있으면 보호 효과는 약하다 (보안이 아니라 은닉)
CDPATH 악용CDPATH가 설정된 환경에서 cd logs가 엉뚱한 디렉터리로 이동할 수 있다. 스크립트에서 cd 후 rm 같은 명령을 쓰면 위험하다
스크립트의 cd 실패cd /target; rm -rf *에서 cd가 실패하면 현재 위치 의 파일이 지워진다

8. 보안관제 관점

관점내용
로그cd는 builtin이므로 auditd execve 이벤트가 발생하지 않는다. 쉘 내부에서 chdir()만 호출된다
Evidence공격자의 이동 경로는 ~/.bash_history, 이후 실행된 명령의 cwd 필드(auditd CWD 레코드)로 추정한다
Detection권한 없는 디렉터리 접근 실패는 기본 로그에 남지 않는다. 민감 경로는 auditd 감시 규칙(-w /root -p rwxa)으로 실패 시도까지 기록할 수 있다
Investigation실행 중인 프로세스의 작업 위치는 ls -l /proc/<PID>/cwd로 확인한다. 웹셸이 띄운 프로세스의 cwd는 업로드 디렉터리인 경우가 많다
[Evidence]  auditd:  type=CWD  cwd="/var/www/html/upload"
                     type=EXECVE argc=2 a0="cat" a1="../../config/db.php"
     ↓
[해석]      cd 자체는 기록되지 않았지만 CWD 레코드로 "어디서" 실행했는지 복원
     ↓
[판단]      웹 업로드 디렉터리에서 설정 파일(DB 비밀번호) 열람 → 자격 증명 탈취 시도

.bash_history는 공격자가 쉽게 지우거나 비활성화(unset HISTFILE)할 수 있으므로 보조 증거 로만 사용한다.


9. 실무에서 자주 발생하는 실수

실수결과예방
cd /dir; rm -rf *cd 실패 시 현재 위치 삭제cd /dir && rm -rf ./* 또는 set -e
디렉터리를 600/644로 설정소유자도 진입 불가, 파일 접근 불가디렉터리는 700/755 계열
/usr/bin/cd로 이동하려 함부모 쉘 위치 불변builtin cd 사용
cd 기록이 audit 로그에 있을 거라 기대기록 없음CWD 레코드와 이후 명령으로 추정
sudo cd /root 시도sudo: cd: command not foundsudo -i 또는 sudo ls /root

10. 실습 체크리스트

[ ] cd, cd ~, cd -, cd .. 의 차이를 확인했다
[ ] $PWD 와 $OLDPWD 값을 확인했다
[ ] x 권한이 없는 디렉터리에 소유자도 들어갈 수 없음을 재현했다
[ ] /root 접근이 거부되는 이유를 권한 칸으로 설명할 수 있다
[ ] cd 가 builtin 이어야 하는 이유를 설명할 수 있다
[ ] cd 가 execve 로그를 남기지 않는다는 점을 이해했다

11. 핵심 정리

  • cwd는 프로세스의 속성이므로 cd는 쉘 내장 명령 이어야 한다.
  • 디렉터리 진입·통과 권한은 x 다. 소유자라도 x가 없으면 들어갈 수 없다.
  • 디렉터리의 r은 목록, x는 진입이며 서로 독립적이다.
  • 스크립트에서 cd 실패를 처리하지 않으면 엉뚱한 위치에서 명령이 실행된다.
  • cd는 execve 로그를 남기지 않는다. auditd CWD 레코드와 /proc/<PID>/cwd로 위치를 추적한다.

12. 다음 편 예고

다음 글 「07. mkdir과 디렉터리 생성」 에서는 새 디렉터리의 권한이 어떻게 정해지는지, Rocky와 Ubuntu에서 같은 mkdir 명령이 왜 다른 권한을 만드는지 를 umask로 설명한다.


참고 자료


시리즈 이동

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글