아파치 톰캣(Apache Tomcat) HTTPS 적용 가이드

안녕하세요, 오늘은 아파치 톰캣 서버에 HTTPS를 적용하는 방법에 대해 상세히 알아보겠습니다. 웹 서비스의 보안이 점점 더 중요해지고 있는 요즘, HTTPS 적용은 필수적인 요소가 되었습니다. 이 글에서는 SSL/TLS 인증서를 생성하고 톰캣 서버에 적용하는 전 과정을 단계별로 설명하겠습니다.

목차

  1. HTTPS/SSL이란?
  2. SSL 인증서 종류
  3. 자체 서명 인증서 생성
  4. 인증 기관(CA)에서 발급받은 인증서 적용
  5. 톰캣 서버에 SSL 적용하기
  6. HTTP를 HTTPS로 리다이렉트 설정
  7. Spring Boot 애플리케이션에 SSL 적용
  8. 문제 해결 및 디버깅
  9. 마치며

HTTPS/SSL이란?

HTTPS(Hypertext Transfer Protocol Secure)는 웹 브라우저와 웹 서버 간의 통신을 암호화하여 보안을 강화하는 프로토콜입니다. SSL(Secure Sockets Layer) 또는 이후 버전인 TLS(Transport Layer Security)를 기반으로 하며, 다음과 같은 이점을 제공합니다:

  1. 데이터 암호화: 전송되는 모든 데이터를 암호화하여 중간에서 정보를 탈취하더라도 해독할 수 없게 합니다.
  2. 데이터 무결성: 전송 중에 데이터가 변조되지 않았음을 보장합니다.
  3. 인증: 사용자가 접속한 웹사이트가 신뢰할 수 있는 사이트임을 인증합니다.

현재 대부분의 웹 브라우저는 HTTPS로 보호되지 않은 사이트에 접속할 경우 경고 메시지를 표시하므로, 웹 서비스 운영자는 HTTPS 적용이 필수적인 상황이 되었습니다.

SSL 인증서 종류

SSL 인증서는 크게 두 가지 방식으로 얻을 수 있습니다:

  1. 자체 서명 인증서(Self-Signed Certificate): 개발용 또는 내부 테스트용으로 무료로 생성하여 사용할 수 있지만, 브라우저에서 신뢰할 수 없는 인증서로 경고가 표시됩니다.
  2. 인증 기관(CA)에서 발급받은 인증서: Let's Encrypt, Comodo, DigiCert 등의 인증 기관에서 발급받은 인증서로, 브라우저에서 신뢰할 수 있는 인증서로 인식됩니다. 일부는 무료(Let's Encrypt)이고, 일부는 유료입니다.

자체 서명 인증서 생성

개발 환경이나 테스트용으로 자체 서명 인증서를 생성하는 방법을 알아보겠습니다. 이 과정에서는 Java에서 제공하는 keytool 유틸리티를 사용합니다.

keytool을 이용한 키스토어 생성

keytool -genkey -alias tomcat -keyalg RSA -keysize 2048 -keystore keystore.jks -validity 3650

위 명령어를 실행하면 다음 정보를 입력하라는 메시지가 표시됩니다:

  • 키스토어 비밀번호
  • 이름과 성(CN, Common Name): 도메인 이름(예: example.com)을 입력
  • 조직 단위명(OU)
  • 조직명(O)
  • 시/도(L)
  • 주/도(ST)
  • 국가 코드(C): 두 글자 국가 코드(예: KR)
  • 입력한 정보가 맞는지 확인(y/n)
  • 키 비밀번호(Enter를 누르면 키스토어 비밀번호와 동일하게 설정)

PKCS12 형식으로 변환 (선택사항)

최신 버전의 톰캣에서는 PKCS12 형식을 권장합니다. JKS 형식의 키스토어를 PKCS12 형식으로 변환하려면:

keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.p12 -deststoretype PKCS12

인증 기관(CA)에서 발급받은 인증서 적용

실제 운영 환경에서는 신뢰할 수 있는 인증 기관에서 발급받은 인증서를 사용하는 것이 좋습니다. 대표적인 무료 인증 기관인 Let's Encrypt를 이용한 인증서 발급 과정을 간략히 살펴보겠습니다.

Let's Encrypt 인증서 발급 및 적용 과정

  1. Certbot 설치:
  2. # Ubuntu/Debian 기준 sudo apt-get update sudo apt-get install certbot
  3. 인증서 발급:
  4. sudo certbot certonly --standalone -d example.com -d www.example.com
  5. 발급받은 인증서 파일:
    • /etc/letsencrypt/live/example.com/cert.pem: 서버 인증서
    • /etc/letsencrypt/live/example.com/privkey.pem: 개인 키
    • /etc/letsencrypt/live/example.com/chain.pem: 인증서 체인
    • /etc/letsencrypt/live/example.com/fullchain.pem: 서버 인증서 + 인증서 체인
  6. PKCS12 형식으로 변환:
  7. sudo openssl pkcs12 -export -in /etc/letsencrypt/live/example.com/fullchain.pem -inkey /etc/letsencrypt/live/example.com/privkey.pem -out /path/to/keystore.p12 -name tomcat -CAfile /etc/letsencrypt/live/example.com/chain.pem -caname root

톰캣 서버에 SSL 적용하기

이제 생성한 또는 발급받은 인증서를 톰캣 서버에 적용하는 방법을 알아보겠습니다.

1. 키스토어 파일 위치 설정

생성된 키스토어 파일(keystore.jks 또는 keystore.p12)을 안전한 위치에 복사합니다. 예를 들어 톰캣 설치 디렉토리 내에 있는 conf 폴더나 별도의 안전한 경로에 저장할 수 있습니다.

2. server.xml 설정

톰캣의 conf 디렉토리에 있는 server.xml 파일을 열고 다음과 같이 HTTPS 커넥터를 추가합니다.

JKS 형식의 키스토어를 사용하는 경우:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="/path/to/keystore.jks"
                     certificateKeystorePassword="비밀번호"
                     type="RSA" />
    </SSLHostConfig>
</Connector>

PKCS12 형식의 키스토어를 사용하는 경우:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="/path/to/keystore.p12"
                     certificateKeystorePassword="비밀번호"
                     certificateKeystoreType="PKCS12"
                     type="RSA" />
    </SSLHostConfig>
</Connector>

3. 추가 속성 설정 (선택사항)

더 세밀한 설정이 필요한 경우 다음과 같은 속성을 추가할 수 있습니다:

<Connector port="8443" protocol="org.apache.coyote.http11.Http11NioProtocol"
           maxThreads="150" SSLEnabled="true"
           scheme="https" secure="true"
           clientAuth="false" sslProtocol="TLS"
           sslEnabledProtocols="TLSv1.2,TLSv1.3"
           ciphers="TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256,TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384,TLS_DHE_RSA_WITH_AES_128_GCM_SHA256,TLS_DHE_RSA_WITH_AES_256_GCM_SHA384">
    <SSLHostConfig>
        <Certificate certificateKeystoreFile="/path/to/keystore.p12"
                     certificateKeystorePassword="비밀번호"
                     certificateKeystoreType="PKCS12"
                     type="RSA" />
    </SSLHostConfig>
</Connector>

4. 톰캣 재시작

설정을 적용하기 위해 톰캣 서버를 재시작합니다.

# Windows
%CATALINA_HOME%\bin\shutdown.bat
%CATALINA_HOME%\bin\startup.bat

# Linux
$CATALINA_HOME/bin/shutdown.sh
$CATALINA_HOME/bin/startup.sh

5. 확인

웹 브라우저에서 https://localhost:8443 또는 https://your-domain:8443으로 접속하여 HTTPS가 정상적으로 적용되었는지 확인합니다. 자체 서명 인증서를 사용한 경우 브라우저에서 경고 메시지가 표시될 수 있으며, 이는 정상적인 현상입니다.

HTTP를 HTTPS로 리다이렉트 설정

사용자가 HTTP로 접속하더라도 자동으로 HTTPS로 리다이렉트되도록 설정할 수 있습니다. 이를 위해 web.xml 파일에 다음 설정을 추가합니다.

1. web.xml 수정

톰캣의 conf 디렉토리에 있는 web.xml 파일을 열고 </web-app> 태그 바로 앞에 다음 내용을 추가합니다:

<security-constraint>
    <web-resource-collection>
        <web-resource-name>Entire Application</web-resource-name>
        <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint>

2. HTTP 커넥터에 리다이렉트 설정

server.xml 파일에서 HTTP 커넥터(보통 8080 포트)에 redirectPort 속성을 추가합니다:

<Connector port="8080" protocol="HTTP/1.1"
           connectionTimeout="20000"
           redirectPort="8443" />

이제 HTTP(8080)로 접속하면 자동으로 HTTPS(8443)로 리다이렉트됩니다.

Spring Boot 애플리케이션에 SSL 적용

Spring Boot 애플리케이션에 내장된 톰캣 서버에 SSL을 적용하는 방법은 다음과 같습니다.

1. application.properties 설정

# SSL 활성화
server.ssl.enabled=true

# 키스토어 설정
server.ssl.key-store=/path/to/keystore.p12
server.ssl.key-store-password=비밀번호
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=tomcat

# 포트 설정 (기본값은 8443)
server.port=8443

2. HTTP 및 HTTPS 동시 지원 (선택사항)

Spring Boot 애플리케이션에서 HTTP와 HTTPS를 동시에 지원하려면 추가적인 설정이 필요합니다. 다음은 이를 위한 구성 예시입니다:

@Configuration
public class ServerConfig {

    @Bean
    public ServletWebServerFactory servletContainer() {
        TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory() {
            @Override
            protected void postProcessContext(Context context) {
                SecurityConstraint securityConstraint = new SecurityConstraint();
                securityConstraint.setUserConstraint("CONFIDENTIAL");
                SecurityCollection collection = new SecurityCollection();
                collection.addPattern("/*");
                securityConstraint.addCollection(collection);
                context.addConstraint(securityConstraint);
            }
        };
        tomcat.addAdditionalTomcatConnectors(redirectConnector());
        return tomcat;
    }

    private Connector redirectConnector() {
        Connector connector = new Connector(TomcatServletWebServerFactory.DEFAULT_PROTOCOL);
        connector.setScheme("http");
        connector.setPort(8080);
        connector.setSecure(false);
        connector.setRedirectPort(8443);
        return connector;
    }
}

문제 해결 및 디버깅

HTTPS 설정 과정에서 문제가 발생할 경우 다음 사항을 확인해보세요:

  1. 키스토어 경로 확인: 설정한 키스토어 파일 경로가 올바른지 확인합니다.
  2. 키스토어 접근 권한: 톰캣 서버가 키스토어 파일에 접근할 수 있는 권한이 있는지 확인합니다.
  3. 비밀번호 확인: 키스토어 비밀번호가 올바르게 설정되었는지 확인합니다.
  4. 로그 확인: 톰캣의 로그 파일(logs/catalina.out 또는 logs/catalina.yyyy-mm-dd.log)을 확인하여 오류 메시지를 분석합니다.
  5. 포트 충돌 확인: 설정한 HTTPS 포트(8443)가 다른 프로세스에 의해 이미 사용 중인지 확인합니다.
  6. # Windows netstat -ano | findstr 8443 # Linux netstat -tulpn | grep 8443
  7. Java 버전 확인: Java 버전에 따라 지원하는 암호화 알고리즘이 다를 수 있으므로, 사용 중인 Java 버전과 호환되는 설정인지 확인합니다.

마치며

SSL/TLS를 적용함으로써 웹 애플리케이션의 보안을 강화하고, 사용자에게 더 안전한 서비스를 제공할 수 있습니다.

HTTPS 적용은 개발 환경에서는 자체 서명 인증서로도 충분하지만, 실제 운영 환경에서는 신뢰할 수 있는 인증 기관에서 발급받은 인증서를 사용하는 것이 좋습니다. Let's Encrypt와 같은 무료 인증 기관을 통해 비용 부담 없이 신뢰할 수 있는 인증서를 발급받을 수 있으니 참고하시기 바랍니다.

보안은 지속적인 관리가 필요한 영역입니다. 정기적으로 인증서를 갱신하고, 보안 취약점에 대응하여 웹 애플리케이션의 보안을 유지하는 것이 중요합니다.

 

'tomcat' 카테고리의 다른 글

아파치 톰캣(Apache Tomcat) 소개 및 설치 가이드  (0) 2025.05.06

+ Recent posts