파일 · 권한 · 사용자 관리 11 / 50 · Part 2. Linux 파일 종류와 속성
실습 환경: Rocky Linux 9.8 · Ubuntu 24.04.5 (Docker 격리 컨테이너, 테스트 계정 analyst)
기초편 연계: 「리눅스 시스템 기초」 13. Linux 파일 종류

1. 들어가며

Part 2 「Linux 파일 종류와 속성」을 시작한다. Part 1에서 파일이 이름·inode·데이터 블록으로 이루어진다는 것을 봤다면, Part 2는 inode에 저장된 속성 을 하나씩 해석한다. 그 첫 번째가 파일 종류(file type) 다.

Linux에는 일곱 가지 파일 종류가 있다. 일반 파일과 디렉터리 외에 심볼릭 링크, 블록 장치, 문자 장치, 소켓, FIFO가 있다. 이번 글에서는 일곱 종류를 실습 환경에서 직접 하나씩 만들어 확인하고, 각 종류가 공격에 어떻게 쓰이는지 정리한다.


2. 핵심 개념

2-1. 7가지 파일 종류

ls -l 첫 글자종류데이터 블록의 의미대표 예
-일반 파일 (regular)실제 내용문서, 실행 파일, 스크립트
d디렉터리이름 → inode 목록/etc, /home
l심볼릭 링크대상 경로 문자열/bin -> usr/bin
b블록 장치없음 (장치 번호만)/dev/sda, /dev/loop0
c문자 장치없음 (장치 번호만)/dev/null, /dev/tty
s소켓없음 (통신 끝점)/dev/log, /run/*.sock
pFIFO (named pipe)없음 (커널 버퍼)mkfifo로 생성

2-2. 장치 파일의 번호

장치 파일은 내용 대신 major, minor 번호 를 가진다. ls -l에서 크기 자리에 7, 0처럼 표시된다.

  • major: 어떤 드라이버인가 (7 = loop, 1 = 메모리 장치, 8 = SCSI 디스크)
  • minor: 그 드라이버의 몇 번째 장치인가

2-3. 블록 vs 문자 장치

구분블록 장치 (b)문자 장치 (c)
입출력 단위고정 크기 블록, 임의 위치 접근바이트 스트림
버퍼링커널 페이지 캐시 사용대체로 직접 전달
예디스크, 파티션, loop터미널, /dev/null, /dev/random

3. 동작 원리

Linux 파일 종류 7가지 — ls -l 첫 글자

파일 종류는 inode의 mode 필드 상위 비트(S_IFMT)에 저장된다. stat의 %f(16진 mode)나 debugfs의 Mode에서 보이는 100644(일반 파일), 40755(디렉터리)의 앞자리가 바로 종류다.

mode 상위 값 (8진)종류
0100000일반 파일
0040000디렉터리
0120000심볼릭 링크
0060000블록 장치
0020000문자 장치
0140000소켓
0010000FIFO

커널은 open()이 들어오면 이 종류를 보고 처리 방식을 결정한다. 일반 파일은 파일 시스템의 데이터 블록으로, 장치 파일은 major 번호에 해당하는 드라이버 로, FIFO는 커널 파이프 버퍼 로 연결한다. 그래서 장치 파일에 대한 접근 권한은 곧 하드웨어(디스크·메모리)에 대한 직접 접근 권한 이 된다.


4. 명령어 실습

cd /data && mkdir lab11 && cd lab11

# 1) 사용자가 만들 수 있는 5종류
echo "text" > regular.txt                  # -  일반 파일
mkdir dir1                                  # d  디렉터리
ln -s regular.txt link.txt                  # l  심볼릭 링크
mkfifo pipe1                                # p  FIFO
python3 -c "import socket,time; s=socket.socket(socket.AF_UNIX); s.bind('app.sock')"   # s 소켓
ls -l

# 2) 커널이 만드는 장치 파일과 시스템 소켓
ls -l /dev/loop0 /dev/null /dev/log

# 3) 소켓·FIFO 찾기
find /dev /run -maxdepth 2 \( -type s -o -type p \) -ls 2>/dev/null | head -5

# 4) 종류를 이름으로 출력
stat -c '%-12n %F' regular.txt dir1 link.txt pipe1 /dev/loop0 /dev/null /dev/log

이 실습 컨테이너에서는 /dev/log 소켓을 만들기 위해 rsyslog를 imuxsock 방식으로 실행했다. 일반 서버에서는 systemd-journald가 /dev/log를 제공한다.


5. 실행 결과

실제 실행 결과 — Rocky Linux 9.8 · analyst@rocky9-lab — 7가지 파일 종류

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

[analyst@rocky9-lab ~]$ cd /data && mkdir lab11 && cd lab11
[analyst@rocky9-lab lab11]$ echo "text" > regular.txt
[analyst@rocky9-lab lab11]$ mkdir dir1
[analyst@rocky9-lab lab11]$ ln -s regular.txt link.txt
[analyst@rocky9-lab lab11]$ mkfifo pipe1
[analyst@rocky9-lab lab11]$ python3 -c "import socket,time; s=socket.socket(socket.AF_UNIX); s.bind('app.sock')"
[analyst@rocky9-lab lab11]$ ls -l
total 8
srwxr-xr-x 1 analyst analyst    0 Sep 24 10:35 app.sock
drwxr-xr-x 2 analyst analyst 4096 Sep 24 10:35 dir1
lrwxrwxrwx 1 analyst analyst   11 Sep 24 10:35 link.txt -> regular.txt
prw-r--r-- 1 analyst analyst    0 Sep 24 10:35 pipe1
-rw-r--r-- 1 analyst analyst    5 Sep 24 10:35 regular.txt
[analyst@rocky9-lab lab11]$ ls -l /dev/loop0 /dev/null /dev/log
srw-rw-rw- 1 root root    0 Sep 24 10:35 /dev/log
brw------- 1 root root 7, 0 Sep 24 10:35 /dev/loop0
crw-rw-rw- 1 root root 1, 3 Sep 24 10:35 /dev/null
[analyst@rocky9-lab lab11]$ find /dev /run -maxdepth 2 \( -type s -o -type p \) -ls 2>/dev/null | head -5
      118      0 srw-rw-rw-   1 root     root            0 Sep 24 10:35 /dev/log
[analyst@rocky9-lab lab11]$ stat -c '%-12n %F' regular.txt dir1 link.txt pipe1 /dev/loop0 /dev/null /dev/log
regular.txt  regular file
dir1         directory
link.txt     symbolic link
pipe1        fifo
/dev/loop0   block special file
/dev/null    character special file
/dev/log     socket

6. 결과 해석

출력해석
srwxr-xr-x ... app.sock 크기 0소켓. 데이터가 파일에 저장되지 않으므로 크기 0
prw-r--r-- ... pipe1 크기 0FIFO. 쓰는 쪽과 읽는 쪽이 동시에 열어야 데이터가 흐른다
lrwxrwxrwx ... link.txt -> regular.txt 크기 11링크 크기는 대상 문자열 regular.txt의 길이(11자)
srw-rw-rw- ... /dev/logsyslog 소켓. 모든 사용자가 로그를 보낼 수 있어야 하므로 666
brw------- ... 7, 0 /dev/loop0블록 장치, major 7(loop) minor 0. root만 접근 (600)
crw-rw-rw- ... 1, 3 /dev/null문자 장치, major 1(mem) minor 3. 누구나 쓸 수 있는 "버리는 곳"
find ... -type s -o -type p/dev, /run 아래 소켓·FIFO 검색 결과로 /dev/log만 나왔다 (컨테이너라 서비스 소켓이 적다)
stat %F 결과regular file, directory, symbolic link, fifo, block special file, character special file, socket — 7종류 이름 확인

/dev/loop0의 권한 600이 중요하다. 일반 서버의 디스크 장치는 보통 brw-rw---- root disk로, root와 disk 그룹 만 접근할 수 있다. 그래서 disk 그룹 가입은 사실상 root 권한 부여와 같다 (39편). 만약 디스크 장치가 666이라면 일반 사용자가 파일 권한을 무시하고 디스크 블록을 직접 읽어 /etc/shadow 내용을 꺼낼 수 있다. 파일 권한 체계는 장치 파일 권한이 지켜진다는 전제 위에서만 의미가 있다.


7. 보안 관점

종류악용 사례확인 방법
- 일반 파일웹셸, 악성 ELFfile, sha256sum (17·18·20편)
l 링크쉘 히스토리 파일을 /dev/null로 연결해 기록을 무력화, /tmp 링크 공격find / -type l -lname '/dev/null'
b/c 장치/dev 밖에 만든 디스크 장치로 권한 우회 (root가 mknod로 생성해 둔 백도어)find / -xdev \( -type b -o -type c \) ! -path '/dev/*'
s 소켓/tmp/.x.sock 같은 로컬 백도어, Docker 소켓(/var/run/docker.sock) 접근 = 사실상 rootfind /tmp /var/tmp /dev/shm -type s, ss -xlp
p FIFO쉘의 입출력을 FIFO와 네트워크 연결로 이어 붙이는 원격 쉘 기법에 사용됨find /tmp -type p + 연결된 프로세스 확인

/var/run/docker.sock에 쓰기 권한이 있는 사용자는 컨테이너를 root로 띄워 호스트 파일 시스템을 마운트할 수 있다. docker 그룹 = root와 동등 하다는 말이 나오는 이유다 (39편).

과장하지 말아야 할 점: /tmp에 소켓이 있다고 해서 모두 백도어는 아니다. X11(/tmp/.X11-unix/X0), tmux(/tmp/tmux-1000/default), 각종 데몬이 정상적으로 소켓을 만든다. 소유 프로세스 를 ss -xlp로 확인해야 한다.


8. 보안관제 관점

[Detection]  EDR: /bin/sh 의 stdin/stdout 이 FIFO(/tmp/f) 와 TCP 소켓에 연결
     ↓
[Evidence]   ls -l /tmp/f → prw-r--r-- www-data
             ls -l /proc/<PID>/fd → 0 -> /tmp/f, 1 -> socket:[48121]
     ↓
[판단]       FIFO 를 이용한 원격 쉘 의심 (웹 서버 계정)
     ↓
[IOC]        원격 IP·포트 (ss -tnp), 생성 시각(stat /tmp/f)
     ↓
[Response]   네트워크 차단 → 프로세스 보존·종료 → 웹 취약점 조사
관점내용
SIEMauditd execve에서 mkfifo, mknod 실행은 드문 이벤트라 탐지 규칙으로 쓰기 좋다
Baseline/dev 밖의 장치 파일, /tmp의 소켓·FIFO 목록을 주기적으로 수집해 비교
Evidence소켓·FIFO는 내용이 없다. 증거는 소유자·생성 시각·연결된 프로세스 다

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

실수결과예방
확장자로 파일 종류 판단종류와 형식을 놓침ls -l 첫 글자 + file
find -type f만으로 의심 파일 검색링크·소켓·FIFO 누락필요 시 -type l,s,p 추가 (GNU find는 쉼표 목록 지원)
장치 파일 크기를 파일 크기로 해석7, 0을 오해major, minor 번호로 읽기
링크를 따라가며 chmod -R, chown -R링크 대상(시스템 파일) 권한 변경-h 옵션, find -type f 대상 한정
/tmp 소켓을 모두 삭제정상 서비스 장애소유 프로세스 확인 후 판단

10. 실습 체크리스트

[ ] 일반 파일·디렉터리·링크·FIFO·소켓을 직접 만들었다
[ ] ls -l 첫 글자로 7가지 종류를 구분했다
[ ] 장치 파일의 major, minor 번호를 읽었다
[ ] stat %F 로 종류 이름을 확인했다
[ ] /dev 밖의 장치 파일이 왜 위험한지 설명할 수 있다
[ ] FIFO 가 원격 쉘에 악용될 수 있는 이유를 이해했다

11. 핵심 정리

  • Linux 파일 종류는 -, d, l, b, c, s, p 일곱 가지이며 inode mode의 상위 비트에 저장된다.
  • 심볼릭 링크의 크기는 대상 경로 문자열의 길이다.
  • 장치 파일은 내용 대신 major·minor 번호를 가지며, 접근 권한이 곧 하드웨어 접근 권한이다.
  • 소켓·FIFO는 크기가 0이고 증거는 소유자·시각·연결된 프로세스다.
  • /dev 밖 장치 파일, /tmp의 FIFO·소켓, /dev/null을 가리키는 로그 링크는 우선 점검 대상이다.
  • 정상 서비스도 소켓을 만든다. 소유 프로세스를 확인한 뒤 판단한다.

12. 다음 편 예고

다음 글 「12. ls -l 출력 해석하기」 에서는 ls -l 한 줄에 들어 있는 10개 정보(종류, 권한 9비트, 특수 권한 표시, ACL +, 링크 수, 소유자, 그룹, 크기, 시간, 이름)를 Rocky와 Ubuntu 실제 출력으로 한 칸씩 해석한다.


참고 자료


시리즈 이동

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

0개의 댓글