소개
Tomcat에서 금융 애플리케이션을 구축할 때, Tomcat을 공용 인터넷에 직접 배치하는 것이 좋지 않다는 것을 빠르게 깨달았습니다. 처음에는 잘 작동했지만, 불안정하고 보안이 어렵고 배포 중 원활하게 유지 관리하기 거의 불가능했습니다.
결국, Nginx를 Tomcat 앞에 두고 Nginx가 Tomcat이 잘 처리하지 못하는 모든 것을 처리하도록 했습니다. 특히 SSL 종료, 유지 관리 모드, 정적 파일 캐싱 및 내부 인프라 세부 사항을 숨기는 작업입니다.
이 글에서는 제가 현재 프로덕션에서 사용하는 정확한 설정을 설명합니다. 일반적인 가이드가 아니라, 제가 배포한 금융 시스템을 위해 특별히 작성된 것으로, 실제 구성과 각 결정의 이유를 포함하고 있습니다.
Tomcat 앞에 Nginx가 필요한 이유
1. Tomcat이 재시작할 때 깔끔한 유지 관리 페이지
금융 시스템에서는 배포나 유지 관리 중에 Tomcat을 재시작해야 하는 경우가 많습니다. Tomcat이 다운되면 사용자는 절대 서버 정보를 노출하는 원시 Tomcat 503 페이지를 보아서는 안 됩니다.
Nginx를 사용하면 사용자는 Tomcat이 완전히 오프라인일 때도 항상 친근한 유지 관리 페이지를 볼 수 있습니다. Nginx는 502 또는 503 응답을 잡아내고 제가 준비한 정적 HTML 페이지를 제공합니다.
2. Nginx에서 SSL이 훨씬 더 간편하다
Tomcat 내부에서 SSL을 구성하는 것은 불필요하게 복잡합니다. 인증서를 Java 키스토어로 변환하고, 커넥터를 관리하며, 여러 형식을 다루어야 합니다.
Nginx에서는 SSL이 간단합니다. 인증서와 개인 키 두 개의 파일만 필요합니다. Nginx가 HTTPS를 종료하고 Tomcat은 로컬호스트에서 평문 HTTP만 받습니다. 인증서 갱신 및 디버깅도 더 쉽습니다.
3. Tomcat이 외부 세계에서 완전히 숨겨져 있다
보안상의 이유로 Tomcat이 공용 사용자에게 포트나 서버 정보를 노출하지 않기를 원합니다. Tomcat은 오직 127.0.0.1:8080에서만 수신합니다.
누군가 제 서버를 스캔하려고 시도하더라도 Tomcat이 존재한다는 것을 전혀 감지할 수 없습니다.
4. 금융 승인을 위한 대형 헤더
시스템의 일부 승인 작업은 헤더나 쿼리 문자열에 긴 금융 애플리케이션 ID 목록을 보냅니다.
이러한 대형 헤더를 지원하기 위해 Nginx를 구성하여 더 큰 헤더 버퍼를 허용했습니다. 그렇지 않으면 기본 헤더 크기가 너무 작아 일부 요청이 실패할 수 있습니다.
5. 대용량 파일 업로드
사용자는 계약서, 송장 및 스캔한 문서를 업로드합니다. Nginx에서 깔끔한 업로드 크기 제한을 설정하여 대용량 파일이 Nginx 검증을 통과하지 않으면 Tomcat에 도달하지 않도록 했습니다.
6. 정적 콘텐츠(CSS, JS, 아이콘) 로딩 속도 향상
Tomcat이 정적 파일을 제공할 수 있지만, Nginx가 훨씬 빠릅니다. 정적 자산에 대한 캐싱을 활성화하여 Nginx가 Tomcat에 부담을 주지 않고 직접 제공하도록 했습니다.
7. 장기 실행 작업을 위한 사용자 정의 타임아웃
금융 시스템의 일부 프로세스는 보고서 생성이나 배치 승인을 포함하여 더 오랜 시간이 걸립니다.
Nginx는 프록시 타임아웃을 완전히 제어할 수 있게 해주어 사용자가 예기치 않은 504 오류를 받지 않도록 합니다.
제가 사용하는 Nginx HTTPS 구성
이 파일은 다음 위치에 보관합니다:
/etc/nginx/sites-available/myapp_https
여기 실제 구성입니다. 기사를 위해 단순화했지만 여전히 정확합니다.
server {
listen 443 ssl;
server_name finance.example.com;
ssl_certificate /opt/myapp/keystore/app.crt;
ssl_certificate_key /opt/myapp/keystore/app.key;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
ssl_ciphers HIGH:!aNULL:!MD5;
ssl_protocols TLSv1.2;
ssl_prefer_server_ciphers on;
large_client_header_buffers 4 65k;
client_max_body_size 100m;
error_page 502 503 = @maintenance;
error_page 404 = @errors;
access_log /opt/myapp/nginx/logs/access.log;
error_log /opt/myapp/nginx/logs/error.log;
location / {
proxy_set_header Host $host;
proxy_set_header X-Forwarded-Host $host;
proxy_set_header X-Forwarded-Server $host;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto https;
proxy_pass http://127.0.0.1:8080;
proxy_buffering off;
proxy_buffer_size 128k;
proxy_buffers 100 128k;
proxy_connect_timeout 180;
proxy_send_timeout 180;
proxy_read_timeout 180;
send_timeout 180;
location ~* \.(css|js|jpg|gif|ico)$ {
proxy_cache cache;
proxy_cache_key $host$uri$is_args$args;
proxy_cache_valid 200 301 302 30m;
expires 30m;
proxy_pass http://127.0.0.1:8080;
}
}
location = / {
return 301 /myapp/;
}
location @maintenance {
root /opt/myapp/nginx/www;
rewrite ^ /maintenance.html break;
}
location @errors {
root /opt/myapp/nginx/www;
rewrite ^ /404.html break;
}
}
이것이 시스템의 핵심입니다. Nginx는 SSL을 처리하고, 트래픽을 Tomcat에 전달하며, Tomcat이 오프라인일 때 유지 관리 페이지를 제공하고, 정적 콘텐츠를 캐시하며, 내부 네트워크 레이아웃을 보호합니다.
HTTP 리디렉션 (포트 80)
모든 HTTP 트래픽을 HTTPS로 리디렉션하는 간단한 구성을 추가했습니다.
/etc/nginx/sites-available/myapp_http
server {
listen 80;
server_name finance.example.com;
return 301 https://$host$request_uri;
}
폴더 구조
Nginx 관련 파일은 전용 애플리케이션 폴더 안에 보관합니다:
/opt/myapp/
keystore/
nginx/
logs/
www/
이렇게 하면 인증서, 로그 및 정적 페이지를 쉽게 관리할 수 있습니다.
설정을 완성하는 Tomcat 구성
Tomcat의 server.xml 내부에서 Tomcat을 로컬호스트에 바인딩하여 외부에서 접근할 수 없도록 설정합니다.
<Connector port="8080"
address="127.0.0.1"
maxHttpHeaderSize="65536"
protocol="HTTP/1.1"
connectionTimeout="20000"
maxThreads="150"/>
Tomcat이 실제 클라이언트 IP와 프로토콜을 이해하도록 설정합니다:
<Valve className="org.apache.catalina.valves.RemoteIpValve"
remoteIpHeader="X-Forwarded-For"
protocolHeader="X-Forwarded-Proto"
protocolHeaderHttpsValue="https"/>
이렇게 하면 시스템이 올바른 클라이언트 IP를 기록하고 HTTPS에 대해 올바르게 동작합니다.
이 설정이 금융 시스템에 잘 작동하는 이유
Nginx를 Tomcat 앞에 두는 것은 전체 시스템을 훨씬 더 전문적이고 안정적으로 만들어 주었습니다. 배포나 재시작 중에 사용자는 일반적인 Tomcat 503 페이지를 마주치지 않습니다. 대신 항상 깔끔한 유지 관리 화면을 보게 되어 시스템이 신뢰할 수 있는 것처럼 보입니다.
Nginx에서 SSL을 처리하는 것도 모든 것을 간소화합니다. 인증서를 관리하고 갱신하며 디버깅하는 것이 더 쉬워지고, Tomcat은 더 이상 HTTPS를 직접 다루지 않아도 됩니다. 또 다른 장점은 보안입니다. Tomcat이 로컬호스트에서만 수신하므로 외부 트래픽에서 완전히 숨겨져 있어 스캔 및 탐색 시도를 없앨 수 있습니다.
성능도 향상됩니다. CSS 및 JavaScript와 같은 정적 파일이 더 빨리 로드되며, 업로드는 Tomcat에 도달하기 전에 확인되고 제한됩니다. 우리의 일부 금융 작업은 대형 헤더나 장기 실행 작업을 포함하며, Nginx는 버퍼 크기와 타임아웃을 완전히 제어할 수 있게 해주어 이러한 작업이 무작위 오류 없이 원활하게 실행됩니다.
Tomcat이 잠시 오프라인이 되는 경우에도 유지 관리 페이지 덕분에 사이트는 여전히 예측 가능한 응답을 제공합니다. 수년 동안 이 설정은 매우 견고하다는 것이 입증되었습니다. 이 설정 덕분에 금융 애플리케이션은 많은 릴리스와 인프라 변경에도 불구하고 거의 제로 다운타임을 달성할 수 있었고, 여전히 예기치 않은 상황 없이 프로덕션 트래픽을 처리하고 있습니다.