[Dockerfile]
#애플리케이션 포트
EXPOSE 80
# 컨테이너 시작 시 Spring Boot 실행
ENTRYPOINT ["sh", "-lc", "exec java $JAVA_TOOL_OPTIONS -jar /app/app.jar --server.port=80"]
컨테이너 내부에서 애플리케이션을 80번 포트로 실행하도록 구성했다.
정상적으로 동작했지만, 코드래빗이 다음과 같은 피드백을 해주었다.
"컨테이너 내부 포트를 80으로 고정하면 non-root 사용자 실행이 불가능합니다."
[원인 분석]
1.Linux의 "특권 포트" 개념
- 0 ~ 1023 포트 = 특권포트
- 이 포트들은 root 권한이 있어야만 바인딩 가능하다.
- Spring Boot -> 80 포트 사용 -> root 권한 필요.
2.컨테이너 보안 문제
- Docker 컨테이너는 보안상 non-root 사용자로 실행하는 방식을 권장한다.
- 지금 구조에서는 --server.port=80 이기때문에 non-root로 실행하면 Permission denied / BindException 발생 -> 애플리케이션 기동 실패 문제가 발생한다.
※root 권한이란?
리눅스에서 모든걸 할 수 있는 "최고 관리자 권한"
- 파일 삭제/수정/권한 변경 전부 가능
- 네트워크, 프로세스, 시스템 설정 전부 제어.
root = 시스템의 주인
non-root = 일반사용자(제한된 권한)
[이해 Time]
//내 상태
외부 사용자 -> http://서버IP:80 -> 컨테이너:80 -> Spring Boot
- 사람들이 80번 문으로 들어온다.
- 사용자가 들어온다고 해서 서버를 마음대로 건드릴 수는 없다.
- GET /api/articles 이런 API 호출뿐 ,,,
IF 취약한 코드 존재.
@GetMapping("/run")
public String run(@RequestParam String cmd) throws Exception {
//문자열을 OS명령어로 넘겨서 실행하는 코드
return Runtime.getRuntime().exec(cmd).toString();
}
- 사용자가 GET /run/cmd=ls 요청 보내면 서버 내부 명령 실행된다.
- GET /run?cmd=rm -rf / 이런식으로 보내면 서버 파일 삭제 시도
지금처럼 80 포트 = root로 실행중이면 서버 파일 삭제 가능하다. DB 접근이나 시스템 명령 실행 가능하다.
root로 실행중이 아니라면 권한부족으로 실패돼서 피해가 제한된다.
[흐름]
GET /run?cmd=rm -rf /
Runtime.getRuntime().exec(cmd);
Spring Boot -> OS(리눅스) 에게 명령 요청 -> rm -rf /실행
[root]
Spring Boot (root)
↓
exec("rm -rf /")
↓
컨테이너 내부 파일 삭제
↓
앱 죽음
[non-root]
Spring Boot (appuser)
↓
exec("rm -rf /")
↓
권한 없음
↓
실행 실패
'코드잇 스프린트 > 실습' 카테고리의 다른 글
| Monew 프로젝트 개선: 뉴스기사 목록 조회 성능 개선 - 복합 인덱스 적용기 (0) | 2026.05.07 |
|---|---|
| 뉴스기사 조회수 증가 동시성 문제 트러블 슈팅 (0) | 2026.04.23 |
| MoNew 프로젝트: ERD 설계 데이터 타입에 대한 고민(VARCHAR vs TEXT) (0) | 2026.04.15 |
| FINDEX 프로젝트: Railway로 프로젝트 배포하기 (0) | 2026.03.17 |
| Findex 프로젝트: 지수정보 update가 이루어지지않는다 400에러 (0) | 2026.03.17 |