서버를 운영하다 보면 수만 개의 파일 속에서 특정 조건의 파일을 찾아내야 할 때가 있습니다. 단순히 이름으로 찾는 것을 넘어, "누가 실행할 수 있는지", "보안상 위험한 설정이 되어 있는지", "용량이 큰 파일만 골라내 백업할 것인지" 등의 복잡한 요구사항을 처리해야 하죠.
이때 리눅스 관리자의 '맥가이버 칼'이 되어주는 도구가 바로 find입니다. 오늘은 실무에서 자주 쓰이지만, 정확한 원리를 모르고 쓰면 위험할 수 있는 3가지 핵심 명령어 패턴을 아주 상세하게 뜯어보겠습니다.

🔍 첫 번째 미션: 실행 가능한 파일을 찾아라
find . -perm -100
개발 서버나 웹 서버를 관리하다 보면 "권한(Permission)" 문제에 자주 부딪힙니다. 특히 스크립트 파일이 실행되지 않거나, 반대로 실행되어서는 안 될 파일이 실행 권한을 가지고 있어 보안 구멍이 되기도 하죠.
이때 사용하는 명령어가 바로 -perm 옵션입니다.
find . -perm -100
이 짧은 명령어에는 비트마스크(Bitmask) 원리가 숨어 있습니다. 하나씩 분해해 볼까요?
1. -perm의 3가지 문법 (이것만 알아도 상위 1%)
많은 분들이 헷갈려 하는 것이 권한 앞의 기호입니다.
- 100 (기호 없음): 정확하게 일치하는 파일만 찾습니다. 즉, 소유자에게만 실행 권한이 있고 나머지 권한(읽기, 쓰기 등)은 아예 없는(--x------) 파일만 찾습니다. 실무에선 잘 안 씁니다.
- -100 (하이픈, 중요!): "최소한 이 권한은 가지고 있는" 파일을 찾습니다. 실행 권한(1)만 있다면, 읽기(4)나 쓰기(2) 권한이 추가로 있어도 모두 검색 대상입니다. (AND 조건)
- /100 (슬래시): 지정한 비트 중 하나라도 켜져 있으면 찾습니다. (OR 조건)
2. 숫자 100의 비밀 (8진수)
리눅스 권한은 3자리 숫자로 표현됩니다. (예: 755, 644)
100을 자리별로 해석하면 다음과 같습니다.
- 첫 번째 자리 (1): User(소유자) 영역입니다.
- 4 (Read) + 2 (Write) + 1 (Execute)
- 즉, "소유자의 실행 권한"을 의미합니다.
- 두 번째 자리 (0): Group(그룹) 영역입니다. 검사하지 않습니다.
- 세 번째 자리 (0): Other(기타 사용자) 영역입니다. 검사하지 않습니다.
💡 요약
의미: "현재 디렉토리(.) 아래에서 다른 권한은 신경 쓰지 말고,
파일 주인이 실행할 수 있는(x) 권한이 켜져 있는 모든 파일을 찾아주세요."
🛡️ 두 번째 미션: 잠재적 백도어를 제거하라 (SetUID)
find /opt/findme/ -type f -perm -4000 -exec rm {} \;
이 명령어는 시스템 엔지니어나 보안 담당자가 서버 점검 시 가장 눈여겨봐야 할 패턴입니다. 잘못 쓰면 시스템을 망가뜨릴 수 있고, 잘 쓰면 해킹 위협을 제거할 수 있습니다.
1. 4000과 SetUID의 위험성
권한이 4자리(4000)로 늘어났습니다. 맨 앞의 자리는 특수 권한을 의미합니다.
- 4 (SetUID): 이 파일이 실행될 때, 실행한 사람이 아니라 파일 주인의 권한(ID)으로 실행됩니다.
- 2 (SetGID): 그룹 권한으로 실행됩니다.
- 1 (Sticky Bit): 공용 디렉토리에서 본인 파일만 삭제 가능하게 합니다.
왜 위험한가요? 💀
만약 해커가 침입해서 /home/hacker/sh 파일을 만들고, 이 파일의 소유자를 root로 바꾼 뒤 SetUID(4000)를 걸어뒀다고 가정해 봅시다.
나중에 해커가 일반 유저로 로그인해서 이 sh 파일을 실행하면, 그 순간 루트(Root) 권한의 쉘을 얻게 됩니다. 이것이 전형적인 백도어(Backdoor) 수법입니다.
2. 명령어 상세 해부
- -type f: 디렉토리는 건드리지 않고 일반 파일만 타깃으로 합니다.
- -perm -4000: 권한이 무엇이든 간에 SetUID 비트가 켜져 있는 파일을 찾습니다.
- -exec rm {} \;:
- find가 파일을 찾을 때마다 rm 명령어를 호출합니다.
- {}는 찾은 파일의 경로로 치환됩니다.
- \;는 명령어의 끝을 알립니다.
⚠️ 치명적 주의사항
이 명령어는 묻지도 따지지도 않고 삭제(rm)합니다.
하지만 리눅스 시스템에는 passwd, ping, sudo 등 정상적으로 SetUID가 필요한 파일들이 존재합니다. 이 명령어를 실수로 /usr/bin/ 같은 곳에서 돌리면 시스템 주요 기능이 마비될 수 있습니다.
[안전한 실무 팁]
삭제하기 전에 반드시 눈으로 먼저 확인하세요!
# 1단계: 먼저 목록과 권한을 확인 (ls -l)
find /opt/findme/ -type f -perm -4000 -exec ls -l {} \;
# 2단계: 확인 후 이상한 파일만 삭제
# (직접 지우거나 검증된 경로에서만 exec rm 사용)
📦 세 번째 미션: 특정 용량 이상의 파일 백업하기
find /opt/findme/ -size +1k -type f -exec cp {} /opt/ \;
로그 파일 관리나 디스크 정리를 할 때 유용한 명령어입니다. 하지만 이 명령어에는 초보자가 반드시 겪게 되는 "데이터 유실"의 함정이 숨어 있습니다.
1. -size 옵션의 디테일
- +1k: 1KB를 초과(GreaterThan)하는 파일입니다.
- 만약 -1k라면? 1KB 미만입니다.
- 그냥 1k라면? 정확히 1KB(반올림 적용)인 파일입니다.
- 단위:
- c: 바이트 (Bytes)
- k: 킬로바이트 (KiB)
- M: 메가바이트 (MiB)
- G: 기가바이트 (GiB)
2. cp와 Flat Copy의 함정 (데이터 유실 주의!)
이 명령어는 찾은 파일을 /opt/라는 단일 디렉토리로 복사합니다. 여기서 문제가 발생합니다.
상황 예시:
- /opt/findme/projectA/config.xml (크기 5KB)
- /opt/findme/projectB/config.xml (크기 10KB)
find는 위 두 파일을 모두 찾아냅니다. 그리고 순서대로 /opt/에 복사를 시도합니다.
- projectA/config.xml을 /opt/config.xml로 복사.
- projectB/config.xml을 /opt/config.xml로 복사. (덮어쓰기 발생!)
결과적으로 /opt/ 디렉토리에는 마지막에 복사된 파일 하나만 남게 됩니다. 원본의 디렉토리 구조(projectA, projectB)가 무시되기 때문입니다.
🚀 해결책: 디렉토리 구조 유지 복사 (--parents)
이 문제를 해결하려면 cp 명령어에 --parents 옵션을 추가해야 합니다.
find /opt/findme/ -size +1k -type f -exec cp --parents {} /opt/ \;
이렇게 하면 복사되는 목적지에 원본의 경로 구조(예: /opt/opt/findme/projectA/...)를 그대로 생성하여 덮어쓰기 문제를 완벽하게 방지할 수 있습니다.
📝 마무리하며
find 명령어는 리눅스라는 거대한 바다에서 원하는 물고기를 낚아 올리는 낚싯대와 같습니다.
- -perm -100: 소유자 실행 권한이 있는 파일을 찾을 때 (스크립트 점검)
- -perm -4000: SetUID 설정된 파일을 찾을 때 (보안 점검 - 삭제 주의!)
- -size +1k: 용량 기반 검색 및 복사 (덮어쓰기 주의!)
이 세 가지 패턴만 확실히 이해하고 계신다면, 파일 관리 자동화 스크립트를 작성하거나 보안 감사를 수행할 때 훨씬 더 자신감 있게 터미널을 다루실 수 있을 것입니다.
오늘 설명드린 명령어들을 테스트 서버에서 직접 입력해 보시면서 감을 익혀보세요! 작은 실수가 큰 사고를 막는 경험이 됩니다.
'일반IT > 리눅스' 카테고리의 다른 글
| 📂 리눅스 부팅의 절대 지도: /etc/fstab 완벽 해부와 트러블슈팅 (0) | 2025.12.20 |
|---|---|
| 🏗️ 리눅스 권한의 마스터키: SetUID, SetGID, Sticky Bit 완벽 해부 (1) | 2025.12.20 |
| 🐳 도커(Docker)의 내부를 파헤치다: Overlay2 파일 시스템 구조 완벽 분석 (0) | 2025.12.04 |
| 내 서버 보안 강화하기: SSH X11 Forwarding 똑똑하게 설정하는 법 🔐 (0) | 2025.10.12 |
| 🚨 갑자기 디스크 용량이 꽉 찼을 때! 리눅스 응급 처치 가이드 (0) | 2025.10.12 |