대상 OS: Rocky Linux 9
서버 침해사고에서 자주 등장하는 경로가 /tmp 입니다.
공격자는 웹쉘이든 취약점이든 어떤 방식으로든 파일을 떨어뜨리고, 그 파일을 실행하려고 합니다.
운영자 입장에서는 “완벽히 막기”보다, 성공 경로를 어렵게 만들어 시간을 벌고 흔적을 남기는 것이 중요합니다.
그중 가장 비용 대비 효과가 좋은 기본기가 /tmp, /var/tmp 같은 임시 경로에 실행/특권을 제한하는 마운트 옵션입니다.
이 글은 Rocky Linux 9에서 /tmp·/var/tmp를 noexec/nosuid/nodev로 하드닝하고, systemd 마운트 유닛(tmp.mount) 기반으로 안정적으로 적용하는 방법과 예외 처리/트러블슈팅까지 정리합니다.
---
1) 왜 /tmp 하드닝이 보안에 직접 도움이 되나
1) 악성 바이너리를 /tmp에 내려받아 실행하는 대표 패턴을 막는다
2) SUID/SGID 바이너리 악용을 임시 경로에서 더 어렵게 만든다
3) 장치 파일(nodev) 기반의 우회 시도를 줄인다
4) “임시 실행”이 필요한 정상 작업을 표준 경로(/usr/local/bin 등)로 옮기게 만들어 운영 습관이 좋아진다
주의
- noexec는 “완전한 실행 차단”이 아니라, 직접 실행(execve) 경로를 막는 성격입니다.
- 예를 들어 /tmp의 스크립트를 bash로 해석 실행하는 우회가 가능할 수 있습니다.
- 그래서 /tmp 하드닝은 ‘단독 방어’가 아니라, 계층 방어의 한 층입니다.
---
2) 변경 전 점검: 지금 /tmp·/var/tmp가 어떻게 마운트되어 있나
1) 현재 마운트 옵션 확인
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /tmp /var/tmp 2>/dev/null || true
mount | grep -E " on /tmp | on /var/tmp " || true
2) /tmp가 별도 tmpfs인지 확인
findmnt /tmp 2>/dev/null || true
3) systemd 마운트 유닛 상태 확인
systemctl status tmp.mount --no-pager 2>/dev/null || true
systemctl status var-tmp.mount --no-pager 2>/dev/null || true
Rocky Linux 9에서는 /tmp가 tmpfs로 운영되는 경우도 있고, 디스크 파티션으로 운영되는 경우도 있습니다. 어떤 방식이든 “마운트 옵션”을 강하게 주는 것이 목표입니다.
---
3) 권장 정책(기본값)
1) /tmp: nodev,nosuid,noexec
2) /var/tmp: nodev,nosuid,noexec
3) /var/tmp는 재부팅 후에도 남을 수 있으므로(/tmp는 tmpfs면 휘발), 공격자가 장기적으로 심어둘 수 있는 지점입니다
그래서 /var/tmp도 같이 묶어주는 게 중요합니다.
---
4) systemd로 /tmp를 tmpfs + 강한 옵션으로 운영(tmp.mount)
이 방법은 “/tmp를 별도 tmpfs로 분리 + 옵션 강제”라는 운영 표준을 만들 때 좋습니다.
1) tmp.mount를 활성화(존재 여부 확인)
systemctl cat tmp.mount 2>/dev/null | sed -n '1,200p' || true
2) tmp.mount 오버라이드 작성
sudo systemctl edit tmp.mount
편집기에 아래를 추가합니다.
[Mount]
Options=mode=1777,strictatime,nodev,nosuid,noexec
3) 적용
sudo systemctl daemon-reload
sudo systemctl enable --now tmp.mount
sudo systemctl restart tmp.mount
4) 적용 확인
findmnt -no TARGET,FSTYPE,OPTIONS /tmp
ls -ld /tmp
- mode=1777은 /tmp의 sticky bit(전통적인 /tmp 권한)를 유지합니다.
---
5) /var/tmp도 동일하게 하드닝(var-tmp.mount)
/var/tmp는 “재부팅 후에도 남는 임시 공간”이라는 특성 때문에, 공격자가 흔적을 오래 남기기 쉬운 지점입니다.
1) var-tmp.mount 오버라이드 작성
sudo systemctl edit var-tmp.mount
아래를 추가합니다.
[Mount]
Options=bind,nodev,nosuid,noexec
2) 활성화/적용
sudo systemctl daemon-reload
sudo systemctl enable --now var-tmp.mount
sudo systemctl restart var-tmp.mount
3) 확인
findmnt -no TARGET,SOURCE,FSTYPE,OPTIONS /var/tmp 2>/dev/null || true
ls -ld /var/tmp
참고
- systemd의 var-tmp.mount는 환경에 따라 /var/tmp를 /tmp로 bind-mount하는 형태일 수 있습니다.
- 핵심은 /var/tmp에서도 nodev,nosuid,noexec가 걸리게 만드는 것입니다.
---
6) 동작 검증: “정말 실행이 막히는지” 테스트
테스트는 운영 영향이 없도록 간단한 파일로만 합니다.
1) 테스트 스크립트 생성
cat > /tmp/hello.sh /dev/null | head -n 40 || true
4) /var/tmp bind-mount 상태 확인
findmnt /var/tmp 2>/dev/null || true
systemctl status var-tmp.mount --no-pager 2>/dev/null || true
---
9) 운영 팁: /tmp 하드닝을 “일회성 설정”으로 끝내지 않기
1) 서버 역할별 표준 템플릿으로 배포한다
2) 예외는 티켓/문서로 남기고 만료 시점을 둔다
3) /tmp 실행이 필요한 작업(설치/배포)은 파이프라인에서 /usr/local/bin으로 이동하도록 개선한다
4) /tmp 하드닝 이벤트(적용/해제)는 변경관리로 기록한다
---
마무리
Rocky Linux 9에서 /tmp·/var/tmp에 noexec/nosuid/nodev를 적용하는 것은, 공격자의 대표 성공 경로를 “더 어렵게” 만드는 저비용 고효율 하드닝입니다.
완벽한 방패는 아니지만, 임시 경로에서의 실행/특권 악용을 줄이고, 정상 운영도 더 표준화된 경로로 유도합니다.
다음 단계로는
- SELinux enforcing 유지
- fapolicyd/감사 로깅으로 실행 이벤트 가시화
- 서비스별 systemd 샌드박싱
같은 계층 방어를 추가하면, /tmp 하드닝의 효과가 훨씬 커집니다.