리눅스 시스템 기초 · 입문편 — 본문의 "N편"은 입문 과정 번호다. 번호별 글과 전체 250편 구성은 통합 로드맵에서 확인할 수 있다.

리눅스 시스템 기초 17 / 50 · Part 2. 파일·명령어·권한
실습 환경: Rocky Linux 9 (10.0.0.200) · Apache httpd
이전 글: 16. chmod와 권한 관리

🔗 심화 시리즈 — 「파일 · 권한 · 사용자 관리」
이 주제를 더 깊게 다룬 실무형 보안 시리즈: 26. chown으로 파일 소유자 변경 · 27. chgrp로 그룹 소유권 변경

1. 들어가며

15편에서 권한 검사가 "프로세스 UID와 파일 소유자가 같은가"에서 시작한다는 것을 봤다. 즉 누가 파일을 소유하느냐 가 권한의 출발점이다. 이번 글은 소유권을 바꾸는 chown, chgrp를 다룬다.

소유권 설계 실수는 실제 침해사고로 자주 이어진다. 대표적인 예가 웹 서버 계정이 웹 루트를 소유하는 구성 이다. 웹 취약점 하나로 실행된 코드가 웹 서버 권한을 가지므로, 그 계정이 소유한 코드 파일을 그대로 수정하거나 새 웹셸을 저장할 수 있다.

이번 글에서 답할 질문:

  • chown, chgrp는 누가, 어떻게 쓸 수 있는가?
  • 웹 루트의 소유권은 어떻게 설계해야 하는가?
  • 계정을 지운 뒤 남는 소유자 없는 파일은 왜 위험한가?

2. 핵심 개념

2-1. 명령어

명령예의미
chown user filechown roror a.txt소유자 변경
chown user:group filechown root:apache config.php소유자·그룹 동시 변경
chown :group filechown :dev a.txt그룹만 변경
chgrp group filechgrp dev a.txt그룹만 변경
chown -Rchown -R root:root /var/www/html하위 전체
chown -hchown -h roror link심볼릭 링크 자체 변경 (대상이 아니라)
chown --reference=A BA와 같은 소유권으로

2-2. 누가 바꿀 수 있는가

작업가능한 사람
소유자 변경root만 (CAP_CHOWN)
그룹 변경root, 또는 파일 소유자가 자신이 속한 그룹으로만

일반 사용자가 자기 파일을 다른 사람 소유로 넘길 수 없는 이유는, 그게 가능하면 디스크 할당량(quota) 회피나 책임 전가가 가능해지기 때문이다.

2-3. 소유권 변경 시 자동 보호

실행 파일의 소유자나 그룹을 바꾸면 커널이 SUID·SGID 비트를 자동으로 해제 한다. 소유자가 바뀐 파일이 이전 설정대로 새 소유자 권한으로 실행되는 사고를 막기 위해서다. 따라서 SUID 파일의 소유권을 바꾼 뒤에는 필요하면 특수 권한을 다시 설정해야 한다.


3. 동작 원리

소유권 설계 — 웹 루트를 누가 소유해야 하는가

3-1. 파일에는 이름이 아니라 번호가 저장된다

inode에는 사용자 이름이 아니라 UID·GID 숫자 가 저장된다. ls -l이 이름을 보여주는 것은 /etc/passwd, /etc/group에서 번호를 이름으로 바꿔 출력하기 때문이다.

그래서 계정을 삭제해도 그 계정이 만든 파일은 숫자 UID로 남는다(orphan file). 나중에 같은 UID로 새 계정을 만들면 새 계정이 옛 파일의 소유자가 된다. 퇴사자 파일에 신규 입사자가 접근하게 되는 식의 사고가 여기서 생긴다.

3-2. 웹 서버의 권한 구조

Apache httpd는 root로 시작해 80번 포트를 연 뒤, 실제 요청 처리 프로세스는 apache 계정 으로 실행한다. 웹 애플리케이션 코드(PHP 등)도 이 apache 권한으로 동작한다. 따라서 권장 구성은 다음과 같다.

대상소유권한이유
웹 루트 코드root:root파일 644, 디렉터리 755apache는 읽기만
설정 파일 (DB 비밀번호)root:apache640apache만 읽기, 다른 사용자 차단
업로드 디렉터리root:apache770 (웹 루트 밖)쓰기는 여기서만, 실행 금지
로그root:root600/640웹 계정이 로그 변조 불가

4. 실습

# 1) 소유권 확인 — 이름과 숫자
ls -l /var/www/html | head
ls -ln /var/www/html | head        # UID/GID 숫자로
stat -c '%U(%u):%G(%g) %n' /etc/shadow /var/www/html

# 2) 소유권 변경
sudo mkdir -p /srv/lab17 && sudo touch /srv/lab17/app.conf
sudo chown root:apache /srv/lab17/app.conf
sudo chmod 640 /srv/lab17/app.conf
ls -l /srv/lab17/app.conf

# 3) 일반 사용자는 소유자를 넘길 수 없음
touch ~/mine.txt
chown root ~/mine.txt              # Operation not permitted
chgrp wheel ~/mine.txt && ls -l ~/mine.txt   # 속한 그룹이면 가능

# 4) chown 시 SUID 해제 확인
sudo cp /usr/bin/true /srv/lab17/t && sudo chmod 4755 /srv/lab17/t
ls -l /srv/lab17/t                 # -rwsr-xr-x
sudo chown roror /srv/lab17/t
ls -l /srv/lab17/t                 # -rwxr-xr-x (s 사라짐)

# 5) orphan 파일 만들기와 찾기
sudo useradd tempuser && sudo -u tempuser touch /tmp/lab17_orphan
sudo userdel tempuser
ls -l /tmp/lab17_orphan            # 소유자가 숫자로 표시
sudo find / -xdev \( -nouser -o -nogroup \) -ls 2>/dev/null | head
sudo rm -f /tmp/lab17_orphan; sudo rm -rf /srv/lab17

5. 결과 분석

아래 출력은 형식 설명용 예시다.

① 웹 루트 점검 결과

drwxr-xr-x. 3 apache apache  /var/www/html
-rw-r--r--. 1 apache apache  index.php
-rw-r--r--. 1 apache apache  config.php
-rw-r--r--. 1 apache apache  .cache.php      ← 2026-09-23 04:12 생성
발견판단
웹 루트 전체가 apache 소유코드 변조가 가능한 구성 — 설계 문제
config.php가 644서버의 모든 사용자가 DB 비밀번호 열람 가능
숨김 이름 .cache.php, 새벽 생성웹셸 의심 — 내용·접근 로그 확인

② orphan 파일

-rw-r--r--. 1 1003 1003 0 Sep 23 11:40 /tmp/lab17_orphan

이름 대신 숫자가 보이면 해당 UID의 계정이 없다 는 뜻이다.


6. 보안 관점

위험원인대응
웹셸 저장·코드 변조웹 계정이 웹 루트 소유코드는 root 소유, 쓰기 영역 분리
설정 파일 비밀번호 노출민감 파일 644root:<서비스그룹> 640
퇴사자 파일 승계계정 삭제 후 UID 재사용삭제 전 파일 처리, -nouser 점검
chown -R 사고심볼릭 링크를 따라가 의도치 않은 경로 변경-h, --no-dereference 확인, 기본은 -P
공격자의 흔적 위장root 획득 후 악성 파일 소유자를 정상 계정으로 변경ctime 변화, auditd chown 기록

7. SOC / 보안관제 활용

7-1. 점검 명령

# 웹 루트에서 웹 계정이 소유하거나 쓸 수 있는 파일
sudo find /var/www/html \( -user apache -o -group apache -perm -g+w \) -type f -ls

# 최근 1일 내 웹 루트에 생성·변경된 스크립트
sudo find /var/www/html -type f \( -name '*.php' -o -name '*.jsp' \) -newermt '1 day ago' -ls

# 소유자·그룹 없는 파일
sudo find / -xdev \( -nouser -o -nogroup \) -ls 2>/dev/null

# 소유권 변경 감사 기록 (15편 perm_mod 규칙)
sudo ausearch -k perm_mod -sc chown -i | tail

7-2. 웹셸 의심 파일 확인 순서

1. stat         → 생성(btime)·변경(ctime) 시각, 소유자
2. file / head  → 실제 형식, 내용 일부 (실행하지 않는다)
3. sha256sum    → 해시 기록, 위협 인텔리전스 조회
4. access_log   → 해당 파일로 들어온 요청, 요청 IP, 파라미터
5. 같은 시각     → 업로드 요청, 다른 새 파일 (14편 find -newerct)

7-3. 분석 흐름

[Alert]   FIM(파일 무결성): /var/www/html/.cache.php 신규 생성 (소유자 apache)
   ↓
[확인]    btime 04:12, 내용에 외부 입력을 명령으로 실행하는 코드
   ↓
[IOC]     access_log: 04:11 upload.php POST (IP 203.0.113.50) → 04:13부터 .cache.php 요청
   ↓
[Root Cause] 업로드 검증 부재 + apache 소유 웹 루트 → 웹셸 저장
   ↓
[Response]  파일 격리·증적, IP 차단, 웹 루트 소유권 root:root 재설정, 업로드 취약점 수정

8. 핵심 정리

  • 소유자 변경은 root만, 그룹 변경은 소유자가 자기가 속한 그룹으로만 가능하다.
  • 실행 파일의 소유권을 바꾸면 SUID·SGID가 자동 해제 된다.
  • inode에는 UID·GID 숫자 가 저장된다. 계정 삭제 후 남은 파일은 orphan이 되고, UID 재사용 시 새 계정이 승계한다.
  • 웹 루트는 root 소유 + 웹 계정 읽기 전용, 쓰기는 웹 루트 밖 전용 디렉터리로 분리한다.
  • 관제 점검: 웹 계정 소유 파일, 최근 생성 스크립트, -nouser/-nogroup 파일, chown 감사 기록.

9. 다음 글

다음 글 「18. Linux 사용자와 그룹」 에서는 소유권의 주체인 계정 자체를 다룬다. /etc/passwd, /etc/shadow, /etc/group의 필드 구조, UID 범위와 시스템 계정, 계정 생성·변경 로그를 관제에서 확인하는 방법을 정리한다.


참고 자료

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

0개의 댓글