본문 바로가기
Springboot

springboot https 적용기

by JunsC 2024. 6. 5.
728x90

 

🚀 Spring Boot에서 HTTPS 적용하는 방법

Spring Boot 애플리케이션을 HTTPS(SSL/TLS)로 실행하려면 SSL 인증서를 설정하고 HTTPS를 활성화해야 해.
주로 Self-Signed Certificate(개발용) 또는 Let's Encrypt/정식 인증서(운영용)를 사용해.

 

 

 

cetons 환경에서 springboot jar 파일로 업로드 하고 난 후 https ssl 적용하려고 했다.

다른 서버에서 서버로 cors 문제를 해결하기 위해서 nginx 와 ssl .p12 그리고

sudo semanage port -l | grep http_port_t

이 명령어로 허용가능한 포트를 확인 후 해당하는 포트로 톰캣 포트로 지정했다.

 

nginx 에서는 당연히 url 분기처리로 해당 로케이션에 맞는 부분에 따라 프록시 패스를 설정해주었다.

 

openssl pkcs12 
-export -in /etc/letsencrypt/live/yourdomain.com/fullchain.pem 
-inkey /etc/letsencrypt/live/yourdomain.com/privkey.pem 
-out /etc/letsencrypt/live/yourdomain.com/fullchain.p12 
-name tomcat 
-CAfile /etc/letsencrypt/live/yourdomain.com/chain.pem 
-caname root

이 코드는 pem -> p12로 변환 후 생성해주는 명령어이다.

우선 연습용 ssl 인증서를 스프링부트에서 사용하려면 pem -> pk12 형식으로 바꿔줘야 한다.

 

🔹 옵션 설명

  • -alias mycert → 인증서의 별칭
  • -keyalg RSA → 암호화 알고리즘
  • -keystore keystore.p12 → 인증서 저장 파일
  • -storetype PKCS12 → .p12 형식 사용
  • -keysize 2048 → 키 크기(2048-bit)
  • -validity 3650 → 인증서 유효 기간 (10년)

 

 

그리고 

server.port= 허용 가능 포트번호들 중 하나
server.ssl.key-store-type=PKCS12
server.ssl.key-store=fullchain.p12
server.ssl.key-store-password=password
server.ssl.key-alias=tomcat

 

이 형식으로 다 설정을 해주었다.

 

🔹 설정 설명

  • server.port=8443 → HTTPS는 보통 443 포트를 사용하지만, 로컬에서는 8443을 많이 씀
  • server.ssl.key-store=classpath:keystore.p12 → .p12 인증서 위치 지정
  • server.ssl.key-store-password=내가설정한비밀번호 → 인증서의 비밀번호
  • server.ssl.key-store-type=PKCS12 → 인증서 형식
  • server.ssl.key-alias=mycert → 생성한 인증서 별칭

 

🛠 HTTP 요청을 HTTPS로 강제 리다이렉트

일반적으로, http://localhost:8080 요청이 들어오면 자동으로 https://localhost:8443로 리다이렉트하도록 설정할 수 있어.

✅ 3️⃣ HttpToHttpsRedirectConfig 설정 추가

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class HttpToHttpsRedirectConfig {

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .requiresChannel(channel ->
                channel.anyRequest().requiresSecure() // 모든 요청을 HTTPS로 강제
            );
        return http.build();
    }
}
 

🔹 설명

  • requiresChannel().anyRequest().requiresSecure() → 모든 HTTP 요청을 HTTPS로 리다이렉트

 

그리고 nginx 에 로케이션을 설정하고 난 후 스프링부트 서버에서 

 

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig {

    @Bean
    public WebMvcConfigurer corsConfigurer() {
        return new WebMvcConfigurer() {
            @Override
            public void addCorsMappings(CorsRegistry registry) {
                registry.addMapping("/**")
                        .allowedOrigins("domain")
                        .allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD")
                        .allowedHeaders("*")
                        .allowCredentials(true);
            }
        };
    }
}

 

설정해주고 jar 로 배포한 후 테스트 했더니 !!!! 

성공했다 !!!

 

그리고 이 스프링부트의 톰캣과 통신하려면 

https://domain:port 으로 해줘야 한다.

 

 

🛠 운영 환경에서는 정식 인증서 사용하기

운영 환경에서는 Let's Encrypt, Cloudflare, DigiCert 같은 정식 SSL 인증서를 사용해야 해.

✅ 4️⃣ Let's Encrypt + Nginx 적용 (예제)

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
 

이렇게 하면 자동으로 SSL 인증서가 설치되면서, HTTP → HTTPS 리다이렉트도 자동으로 설정돼.

 

🎯 정리

단계작업 내용

1️⃣ keytool로 Self-Signed 인증서 생성 (keystore.p12)
2️⃣ application.properties에서 HTTPS 설정
3️⃣ HTTP → HTTPS 리다이렉트 적용
4️⃣ 운영 환경에서는 정식 SSL 인증서 사용 (Let's Encrypt 등)

 

이제 Spring Boot 애플리케이션을 HTTPS로 안전하게 실행할 수 있어! 🚀

 

 

 

별책부록

 

 

🎯 1. HTTPS + HTTP2 활성화 (성능 최적화)

기본적으로 HTTPS를 사용하면 HTTP/2를 함께 사용하면 속도와 효율성이 향상돼.
Spring Boot에서는 간단하게 server.http2.enabled=true 설정을 추가하면 돼.

✅ application.properties

server.port=8443
server.ssl.key-store=classpath:keystore.p12
server.ssl.key-store-password=내가설정한비밀번호
server.ssl.key-store-type=PKCS12
server.ssl.key-alias=mycert
server.http2.enabled=true
 

🚀 HTTP/2 장점

  • 멀티플렉싱(Multiplexing) → 하나의 연결로 여러 요청 처리 가능
  • 헤더 압축(Header Compression) → 네트워크 트래픽 감소
  • 서버 푸시(Server Push) → 클라이언트가 요청하기 전에 리소스 미리 전송 가능

💡 주의: HTTP/2는 HTTPS 환경에서만 지원됨!

 

 

 

🎯 2. HSTS (HTTP Strict Transport Security) 적용

HSTS(Strict-Transport-Security)를 설정하면 브라우저가 강제로 HTTPS만 사용하도록 만들 수 있어.
이를 통해 MITM(중간자 공격)을 방지하고 보안성을 강화할 수 있어.

✅ Security 설정 추가 (SecurityConfig.java)

import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.web.SecurityFilterChain;

@Configuration
public class SecurityConfig {

    public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
        http
            .headers(headers -> headers
                .httpStrictTransportSecurity(hsts -> 
                    hsts.includeSubDomains(true)
                        .maxAgeInSeconds(31536000) // 1년 (1년 동안 HTTPS만 사용하도록 브라우저에 지시)
                )
            );
        return http.build();
    }
}

 

💡 브라우저가 강제로 HTTPS를 사용하도록 만들어 HTTPS 연결 우회를 방지함.

 

 

🎯 3. Let's Encrypt 자동 갱신 (운영 환경)

운영 환경에서는 Let's Encrypt SSL 인증서를 사용하여 HTTPS를 적용하고, 이를 자동 갱신해야 해.

✅ Nginx + Let's Encrypt 설정 (예제)

sudo apt install certbot python3-certbot-nginx
sudo certbot --nginx -d example.com -d www.example.com

 

🔹 자동 갱신 설정

 

sudo crontab -e
 
0 3 * * * certbot renew --quiet

 

💡 매일 새벽 3시에 자동으로 SSL 인증서를 갱신함.

 

 

 

🎯 4. HTTPS + Mutual TLS (mTLS) 적용

기본 HTTPS는 서버 인증만 수행하지만, Mutual TLS(mTLS)를 적용하면 클라이언트도 인증서로 인증해야 해.
이를 통해 API 요청을 더욱 안전하게 만들 수 있어.

✅ application.properties

server.ssl.client-auth=need
server.ssl.trust-store=classpath:truststore.p12
server.ssl.trust-store-password=trustpassword
 

💡 client-auth=need → 클라이언트 인증서를 필수로 요구

✅ 클라이언트 인증서 발급 (client.p12)

keytool -genkey -alias client -keyalg RSA 
-keystore client.p12 -storetype PKCS12 -keysize 2048 -validity 3650

 

이제 API 요청 시 서버와 클라이언트가 서로 인증서 검증을 진행해야 요청이 정상 처리됨! 🚀

 

 

 

🎯 5. HTTPS 로드밸런서 뒤에 Spring Boot 실행하기

운영 환경에서는 보통 로드밸런서(LB, Load Balancer) 뒤에서 HTTPS 트래픽을 받아서 처리해.
이 경우, Spring Boot 내부에서는 HTTP로 실행하되, X-Forwarded-Proto 헤더를 통해 HTTPS 요청을 감지해야 해.

✅ application.properties

server.forward-headers-strategy=native

 

💡 이 설정을 추가하면, Spring Boot가 로드밸런서에서 전달하는 X-Forwarded-Proto 헤더를 인식해서 올바른 URL을 유지할 수 있어.

 

 

🎯 6. HTTPS 트래픽을 HTTP로 다운그레이드 하기 (Reverse Proxy)

일부 서비스는 HTTPS 트래픽을 받아서 내부적으로 HTTP로 변환해야 할 때가 있어.
이 경우, Nginx Reverse Proxy를 이용해서 HTTPS를 HTTP로 변환할 수 있어.

✅ Nginx 설정 (HTTPS → HTTP 변환)

server {
    listen 443 ssl;
    server_name example.com;

    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;

    location / {
        proxy_pass http://localhost:8080;
        proxy_set_header X-Forwarded-For $remote_addr;
        proxy_set_header X-Forwarded-Proto https;
    }
}

 

💡 외부에서는 HTTPS로 접속하지만, 내부에서는 HTTP로 통신하도록 설정

 

 

🎯 7. HTTPS + WebSocket (wss://) 설정

Spring Boot에서 HTTPS 환경에서 WebSocket을 사용하려면 wss:// 프로토콜을 사용해야 해.
기본적으로 WebSocket은 HTTP 프로토콜을 사용하기 때문에 HTTPS 환경에서는 wss://로 변경해야 해.

✅ WebSocket 설정 (WebSocketConfig.java)

import org.springframework.context.annotation.Configuration;
import org.springframework.web.socket.config.annotation.EnableWebSocket;
import org.springframework.web.socket.config.annotation.WebSocketConfigurer;
import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

@Configuration
@EnableWebSocket
public class WebSocketConfig implements WebSocketConfigurer {
    @Override
    public void registerWebSocketHandlers(WebSocketHandlerRegistry registry) {
        registry.addHandler(new MyWebSocketHandler(), "/ws")
                .setAllowedOrigins("https://example.com"); // HTTPS 환경에서만 허용
    }
}

 

💡 외부에서는 wss://example.com/ws로 접속하도록 설정!

 

 

🔥 고급 HTTPS 기술 요약

기술설명

HTTP/2 활성화 성능 최적화 (멀티플렉싱, 서버 푸시)
HSTS 적용 브라우저에서 HTTP 접속 차단, 강제 HTTPS
Let's Encrypt 자동 갱신 인증서 갱신 자동화 (certbot renew)
Mutual TLS (mTLS) 클라이언트 인증서 검증 (보안 강화)
로드밸런서 뒤 HTTPS 처리 X-Forwarded-Proto 활용
Reverse Proxy로 HTTPS → HTTP 다운그레이드 Nginx에서 내부 트래픽 변환
HTTPS + WebSocket (wss://) 보안 WebSocket 지원

이제 Spring Boot 애플리케이션을 HTTPS로 강력하게 보호하고, 운영 환경에서 최적화할 수 있어! 🚀🔥

 

"이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다."