설치 직후 webapps 에는 manager·host-manager·docs·examples·ROOT 다섯 개가 들어 있습니다. 앞의 넷은 운영 서비스에 필요 없고 관리 콘솔·문서·예제 코드가 공격 경로가 됩니다.
ROOT 는 지우지 않고 우리 서비스 페이지로 교체합니다. 기본 안내 페이지를 그대로 두면 서버가 아직 설정되지 않았다는 신호가 됩니다.
ErrorReportValve 는 500 같은 오류가 났을 때 보여줄 화면을 담당합니다. 기본값은 스택 트레이스와 Tomcat 버전을 그대로 보여줍니다.
showReport="false", showServerInfo="false" 로 끄면 사용자에게는 간단한 오류만 보이고 내부 정보는 로그에만 남습니다.
Tomcat 은 기본적으로 응답 헤더 Server 에 정확한 버전 문자열을 넣습니다. Connector 의 server 속성에 다른 값을 채우면 그 값이 대신 나갑니다.
값을 비워도 되지만, 빈 값보다는 WebServer 처럼 의미 없는 이름을 넣어야 일부 클라이언트가 헤더 누락을 오류로 취급하는 문제를 피할 수 있습니다.
Server 요소의 port·shutdown 속성이 종료 포트와 비밀 명령입니다. 기본값 shutdown="SHUTDOWN" 은 누구나 아는 값이라 그대로 두면 안 됩니다.
| 방식 | 설정 | 종료 방법 |
|---|---|---|
| 비밀 명령으로 보호 | shutdown 값을 임의 문자열로 | 네트워크로 그 문자열을 보내야 종료 |
| 포트 자체를 끔 | port="-1" | kill -TERM 또는 systemctl stop 만 가능 |
포트를 완전히 끄면 네트워크로는 절대 종료할 수 없어 더 안전하지만, 그만큼 서버 접근 권한이 있어야만 종료할 수 있습니다.
conf 폴더는 실행 중 절대 바뀌면 안 되므로 쓰기 권한을 모두 뺍니다(chmod a-w). logs·temp·work 는 실행 계정이 계속 써야 하므로 쓰기 권한을 남깁니다.
webapps 도 실행 계정이 쓸 수 있게 두면, 웹 애플리케이션 취약점으로 파일이 업로드될 때 그대로 war 로 배포될 위험이 생깁니다. 배포는 별도 계정으로만 하고 실행 계정은 읽기만 하게 막습니다.
배포 계정과 실행 계정(tomcat)을 나누면 애플리케이션이 뚫려도 피해가 그 프로세스 권한 안으로 제한됩니다. chown -R tomcat:tomcat 으로 소유권을 tomcat 계정에 주되, 쓰기 권한 자체는 2.5 의 원칙을 따릅니다.
로그인 불가 시스템 계정(레슨 01 의 useradd --system --shell /sbin/nologin)이라는 전제도 그대로 유지합니다.
web.xml 의 session-config 에서 session-timeout(분 단위)으로 방치된 세션이 오래 살아있지 않게 합니다. cookie-config 의 http-only 는 자바스크립트로 쿠키를 읽지 못하게 막아 XSS 피해를 줄입니다.
secure 는 HTTPS 연결에서만 쿠키를 보내게 합니다. HTTP 로도 서비스한다면 이 값을 켜는 순간 HTTP 쪽 세션이 끊기므로 nginx HTTPS 전환(레슨 07)과 함께 적용해야 합니다.
context.xml 의 Context 요소에 useHttpOnly="true" 를 두면 기본값으로도 적용됩니다. CookieProcessor 의 sameSiteCookies="strict" 는 다른 사이트에서 걸어오는 요청에 쿠키를 안 실어 CSRF 위험을 줄입니다.
스레드 덤프는 그 순간 JVM 안의 모든 스레드가 무엇을 하고 있는지 찍은 사진입니다. 응답이 갑자기 느려졌을 때 jcmd <PID> Thread.print 로 뜬 다음, BLOCKED 상태 스레드가 많은지, 같은 락을 여럿이 기다리는지를 봅니다.
한 번만 뜨면 순간 상태만 보이므로, 느려지는 동안 몇 초 간격으로 두세 번 떠서 비교하면 원인을 좁히기 쉽습니다.
힙 덤프는 그 순간 힙에 들어있는 객체를 통째로 파일로 남깁니다. jcmd <PID> GC.heap_dump 파일 로 즉시 뜨거나, -XX:+HeapDumpOnOutOfMemoryError 로 OOM 이 날 때 자동으로 남게 미리 설정해 둡니다(레슨 03 의 setenv.sh 참조).
힙 덤프 파일은 수백 MB 에서 수 GB 까지 커질 수 있어 디스크 여유 공간을 먼저 확인하고, 분석 후에는 지워야 합니다.
배포 직후나 장애 대응 때 매번 같은 항목을 손으로 확인하면 빠뜨리기 쉽습니다. 스크립트로 만들어 한 번에 돌립니다.
| 항목 | 확인 방법 |
|---|---|
| 포트 | ss -ltn 으로 LISTEN 여부 |
| PID | PID 파일과 실제 프로세스 존재 |
| 디스크 | df -h 여유 공간 |
| 로그 크기 | du -sh 로 급증 여부 |
레슨 01 에서 본 것처럼 새 버전은 기존 폴더를 건드리지 않고 별도 폴더에 풀고 current 심볼릭 링크(symbolic link)만 돌립니다. 인스턴스 설정(tomcat-inst)은 버전과 분리돼 있어 그대로 유지됩니다.
전환 직후에는 점검 체크리스트로 포트·PID·응답을 확인해야 문제를 바로 발견합니다.
문제가 보이면 current 링크를 이전 버전 폴더로 다시 돌리고 재시작하면 됩니다. 파일을 다시 풀거나 설정을 복원할 필요가 없어 배포와 대칭인 절차입니다.