>Backouts_
Published on

리눅스 디렉터리 구조 살펴보기 (1)

Authors
  • avatar
    Name
    Backouts
    Twitter

리눅스를 처음 접하면 가장 먼저 보이기 시작하는 이름들이 있습니다.
/bin, /etc, /usr, /var, /home, /proc 같은 디렉터리들입니다.
명령어로 리눅스를 다루기 시작하면 자연스럽게 이런 경로들을 사용하게 되지만,
처음에는 왜 이렇게 복잡하게 나뉘어 있는지 이해가 가지 않습니다.

이번 글에서는
각 디렉터리가 어떤 역할을 하고,
왜 이런 구조로 만들어졌는지를 살펴보겠습니다.

간단하게 정리한 글로,
다음에 리눅스 명령어에 관한 글을 읽는 데 필요한 기초 지식입니다.


리눅스의 모든 것은 루트 ( / ) 에서 시작된다.

리눅스에서 모든 파일과 디렉터리의 시작점은 바로 최상위 디렉터리 / 입니다.
우리가 사용하는 모든 경로는 이 루트를 기준으로 뻗어 나가며,
시스템의 전체 구조가 이 한 지점에서 출발합니다.

재미있는 점은, 파티션을 나누어 사용하는 방식도 윈도우와 다르다는 것입니다.
Windows는 C:, D:처럼 드라이브로 나누어 사용하지만,
리눅스는 파티션이 여러 개여도 특정 디렉터리에 마운트하여 루트 아래의 디렉터리 중 하나처럼 사용합니다.

마운트란 특정 파티션이나 저장장치를 리눅스의 디렉터리 구조에 연결하는 작업을 의미합니다.
윈도우에 USB를 삽입하면 E: F:와 같이 드라이브 문자로 나누어 자신의 루트 디렉터리를 가지지만
리눅스는 / 아래 /mnt/usb 등 원하는 디렉터리에 연결하여 사용한다는 차이점이 있습니다.

이제 리눅스의 기본 디렉터리 구조를 알아보겠습니다.
아래는 리눅스의 디렉터리 구조를 간단히 나타낸 것입니다.
FHS(Filesystem Hierarchy Standard) 표준을 기준으로 한 예시이며,
실제 배포되는 리눅스 배포판(Ubuntu 등)에 따라 약간의 변경 점이 있습니다.

/
├── bin
├── boot
├── sbin
├── etc
├── var
├── usr
├── lib
├── home
├── root
├── proc
├── dev
├── mnt
└── tmp

/bin - 시스템 관리에 필요한 최소한의 명령어들

어떤 상황에서도 반드시 실행되어야 하는 핵심 명령어들이 /bin에 모여 있습니다.

예: ls, cp, mv, rm, cat, mkdir, sh

왜 이 명령어들이 여기에 있을까요?
리눅스 부팅 중 오류가 발생해서 **응급 쉘(emergency shell)**로 부팅됐다고 상상해보면 이해가 됩니다.

emergency shell은 최소한의 환경으로 시스템을 복구하기 위한 쉘이기 때문에
/usr가 마운트 되지 않고, 네트워크도 불가능한 상태일 수 있습니다.
그에 비해 /bin은 반드시 루트 파일 시스템에 포함되어 있기 때문에 접근이 가능합니다.

하지만 최근에는 /usr역시 / 파일 시스템에 포함되는 경우가 많기 때문에
/bin/usr/bin은 사실상 통합되고 있다고 볼 수 있습니다.
아래 사진을 보시면 /bin 디렉터리가 /usr/bin으로 심볼릭 링크가 걸려있는 것을 확인할 수 있습니다.

ls -la bin 결과
그림 1. ls -la bin 결과

/sbin - 시스템 관리자들이 사용하는 명령어들

/sbin에는 일반 사용자가 함부로 실행하면 위험할 수 있는 시스템 관리 명령어들이 있습니다.

예를 들어 다음과 같은 명령어들이 있습니다.

  • fsck : 파일시스템 검사
  • fdisk : 디스크 파티션 편집
  • iptables, ip : 네트워크, 방화벽 설정
  • mount, umount : 파일시스템 마운트/언마운트
  • reboot : 시스템 종료 및 재부팅

이 폴더가 /bin과 분리된 이유는 명확합니다.
일반 사용자가 사용하면 안 되는 명령어들이기 때문입니다.
시스템에 영향을 주는 명령어들은 거의 모두 /sbin에 있다고 이해하시면 편합니다.

아래 사진처럼 /sbin 디렉터리가 /usr/sbin으로 심볼릭 링크가 걸려있는 것으로
/bin과 마찬가지로 /sbin역시 사실상 /usr/sbin과 통합되고 있다고 볼 수 있습니다.

레거시 시스템과 같은 옛 리눅스 환경이나 임베디드 시스템, CTF 실습 환경에서는
여전히 이 구조가 유지되고 있는 경우가 있기 때문에, /bin, /sbin 디렉터리의 존재 이유를 알아두는 것이 좋습니다.

ls -la sbin 결과
그림 2. ls -la sbin 결과

/etc - 리눅스의 행동을 결정하는 설정들

리눅스는 설정도 대부분 텍스트 파일로 이루어져 있습니다.
이 설정파일들이 위치하는 곳이 바로 /etc입니다.

대표적인 것들만 예시로 보겠습니다.

  • /etc/passwd : 사용자 계정 정보
  • /etc/ssh/sshd_config : SSH 서버 설정
  • /etc/fstab : 부팅시 자동 마운트 설정
  • /etc/systemd/system/*.service : 서비스 파일

리눅스의 각 서비스들이 어떻게 동작할지를 결정하는 부분이 이 디렉터리에 거의 모두 담겨있습니다.

설정에 문제가 생겼을 때 가장 먼저 /etc를 열어보는 이유가 바로 이것입니다.


/var - 로그와 계속 변하는 데이터들의 저장소

/var는 이름 그대로 variable, 계속 변하는 데이터를 보관하는 곳입니다.

대표적인 사용 예시입니다.

  • /var/log : 시스템 및 서비스 로그
  • /var/lib/mysql : 데이터베이스 데이터
  • /var/lib/docker : 도커 이미지 및 컨테이너 데이터
  • /var/www/html : 웹 서버 루트 디렉터리

예시 중 /var/log는 서버 운영에서 가장 중요한 디렉터리 중 하나입니다.
문제가 발생했을 때,
에러 메시지와 같은 오류의 원인을 찾을 수 있는 흔적이 /var/log에 기록됩니다.

그리고 한 가지 더 확인할 점은,

디스크 용량이 갑자기 100%가 되는 문제의 원인 대부분이 이 /var 때문입니다.
DDos 공격이나, 로그 폭주 공격을 통해
로그가 폭증하거나, 데이터베이스가 갑자기 커지면
전체 시스템이 멈춰버릴 수도 있습니다.

그렇기에 대부분의 운영 환경에서는 /var를 별도 파티션으로 분리해서 관리합니다.

예 : DDos로 인해 /var/log의 로그가 폭증해 용량이 가득찬 경우 ssh 로그인 불가, 파일 쓰기 불가, systemd 서비스 장애 등의 문제가 발생할 수 있습니다.


/home - 일반 사용자들의 작업 공간

따로 기본 디렉터리를 설정하지 않았다면,
일반 사용자 계정들은 /home 아래에 자신만의 디렉터리를 갖습니다.

예: /home/ubuntu, /home/developer

프로젝트, 문서, 개발 환경 설정 등 대부분의 개인 작업은 이곳에서 이루어집니다.

실제로 리눅스를 사용자 관점에서 사용하면
가장 많이 머물게 되는 곳이 /home 디렉터리 내부입니다.


/root - 관리자 계정의 작업 공간

관리자인 root 계정의 홈 디렉터리인 /root입니다.
이 공간이 /home/root가 아닌 데에는 이유가 있습니다.

부팅 초기 단계에는 /home마운트되지 않았을 수 있습니다.
하지만 관리자는 언제든지 필요한 작업을 수행해야 하기 때문에,
/root라는 별도의 홈 디렉터리를 사용합니다.

그래서 root 계정의 홈은 항상 루트 파티션 바로 아래에 있습니다.
권한도 매우 엄격하게 설정되어 있고,
보안적으로 민감한 디렉터리 중 하나입니다.


/proc - 커널과 프로세스 정보의 창

/proc은 조금 특별한 공간입니다.
일반 디렉터리처럼 보이지만,
실제로는 커널이 생성한 정보를 보여주는 가상 파일시스템입니다.

대표적인 예시입니다.

  • /proc/cpuinfo : CPU 정보
  • /proc/meminfo : 메모리 사용량
  • /proc/uptime : 시스템 가동 시간
  • /proc/PID : 특정 프로세스 정보

이 파일들은 텍스트처럼 읽을 수 있지만 디스크에 실제로 저장된 적이 없습니다.
읽는 순간 커널이 내부 정보를 문자열로 변환해 보여주는 방식입니다.

그래서 ps, top, htop 같은
시스템 자원을 확인하는 명령어들도 결국
/proc 내부의 파일을 계속 읽으면서 정보를 갱신하는 것입니다.


/dev - 시스템의 모든 디바이스 파일들

리눅스의 철학 중 하나는 모든 것은 파일처럼 다룬다입니다.
그래서 SSD, 키보드, 터미널, 랜카드 등의 디바이스들도
모두 /dev 아래 파일로 다룰 수 있습니다.

이곳에 있는 파일들은 실제 파일 데이터가 아니라
커널이 하드웨어 장치를 추상화한 인터페이스입니다.

대표적인 예시는 다음과 같습니다.

  • /dev/sda : 일반 디스크
  • /dev/sda1 : 디스크 파티션
  • /dev/usb/ : USB 장치
  • /dev/tty : 터미널
  • /dev/null : 데이터 버리는 장소

이 구조 덕분에 프로그램들이 복잡하고 장치마다 다른 전용 API 대신
open(), read(), write() 등의 파일 I/O 만으로도 장치를 다룰 수 있습니다.
즉, 장치를 파일처럼 다룰 수 있기에 개발과 관리가 훨씬 단순해집니다.

/dev가 파일인 점을 활용하는 예시

  • cat /dev/audio > sound.raw : 오디오 장치에서 소리 데이터를 읽어 sound.raw에 저장
  • dd if=/dev/sda of=backup.img : 디스크 전체를 이미지 파일로 백업
  • dd if=backup.img of=/dev/sda : 이미지 파일을 디스크에 복원
  • command 2> /dev/null : 명령어의 에러 출력을 버리기

/usr - 사용자 프로그램과 라이브러리들의 저장소

/usr은 이름 때문에 user와 연관된 것처럼 보이지만,
실제로는 프로그램, 라이브러리, 문서 등이 저장되는 공간입니다.

대부분의 명령어는 /usr/bin 아래에 설치됩니다.

예: python3, git, curl, systemctl

또한 라이브러리는 /usr/lib,
아이콘, 문서는 /usr/share 아래에 있습니다.

리눅스 프로그램이 어디에 설치됐는지 헷갈릴 때는
대부분 /usr 내부에 있습니다.


/tmp - 임시 파일들의 저장소

/tmp프로그램이 임시 데이터를 저장할 때 사용하는 곳입니다.

/tmp에 생성되는 임시파일 예시입니다.

  • 프로세스 간 통신 (IPC) 파일
  • 파일 다운로드 중간 작업
  • 설치 프로그램의 임시 파일
  • 웹서버가 요청을 처리하면서 생성되는 임시 파일
  • 문서의 자동 저장 사본

특이사항

/tmp 디렉터리의 권한을 확인해보면 1777 로 성정되어 있습니다.
여러 사용자가 동시에 사용하되
서로의 파일을 지울 수 없도록 하기 위해
sticky bit (1000)을 설정해둔 것 입니다.

stat tmp 결과
그림 2. stat tmp 결과

정리하며

리눅스의 디렉터리 구조는 처음엔 쓸데없이 복잡해 보이지만,
각 디렉터리의 목적을 알고 보면 오히려 편하고 안정적인 설계인 걸 느낄 수 있습니다.

설정은 /etc
로그, 데이터는 /var
프로그램은 /usr
사용자 파일은 /home
장치는 /dev
커널 정보는 /proc

이 구조가 머릿속에 들어오면
리눅스를 다루기가 편해지며
명령어들의 작동 방식을 이해할때 도움이 됩니다.

오늘 알아본 디렉터리들 외의
/opt, /sys, /mnt, /media, /misc, /lib
다루지 않은 디렉터리들은 다음 편에서 정리하도록 하겠습니다.