Spring Cloud + MSA 애플리케이션 개발 8(Spring Cloud Bus + 설정 정보의 암호화 처리)

지원·2024년 2월 26일
0

MSA개발

목록 보기
8/15
post-custom-banner

Spring Cloud Bus

Actuator refresh 는 만약 변경 사항이 있을때 모든 MS 가 refresh 를 해야하는 번거로움이 있었다.

  • Spring Cloud Bus 는 그러한 번거로움을 해결할 수 있다.

Spring Cloud Bus 사용

  • 분산 시스템의 노드를 경량 메시지 브로커와 연결
  • 여기서 노드는 Microservice(user-service...) 라고 생각하면 되고 우리가 사용할 메시지 브로커는 RabbitMQ 이다.
  • 상태 및 구성에 대한 변경 사항을 연결된 노드에게 전달(Broadcast)
  • 전달할때는 String 값 , 객체 , resource 등 다양한 것들을 전달할 수 있다.

정리하면 Spring Cloud Bus 가 Spring Cloud Config Server 에 직접 변경 사항을 push 한다고 생각하면 된다.

  • HTTP POST /busrefresh 로 호출하면 된다 (bus-refresh EndPoint)
  • endpoint 를 호출할 때는 어디서든 호출해도 된다.
  • 즉 user-service , spring cloud config server , apigateway-service 등 아무곳에서 호출하면 된다.
  • 아무곳에서 호출하기만 하면 Spring Cloud Bus 가 변경된 사항을 감지하고 자기와 연결된 다른 클라이언트(MS) 한테 업데이트를 하도록한다.

AMQP 와 Kafka

  1. AMQP (Advanced Message Queuing Protocol) : 메시지 지향 미들웨어를 위한 개방형 표준 응용 계층 프로토콜
  • 메시지 지향 , 큐잉 , 라우팅 , 신뢰성 , 보안
  • Erlang , RabbitMQ 에서 사용
  1. Kafka
  • Apache Sotfware Foundation 이 Scalar 언어로 개발한 오픈 소스 메시지 브로커 프로젝트
  • 분산형 스트리밍 플랫폼
  • 대용량의 데이터를 처리 가능한 메시징 시스템

RabbitMQ vs Kafka

  1. RabbitMQ
  • 메시지 브로커
  • 초당 20개 이상 메시지를 소비자에게 전달
  • 메시지 전달 보장 , 시스템 간 메시지 전달
  • 브로커 , 소비자 중심
  1. Kafka
  • 초당 100k+ 이상의 이벤트 처리
  • Pub/Sub 로 나뉘어지고 Topic 에 메시지를 전달
  • Ack 를 기다리지 않고 전달 가능
  • 생산자 중심

RabbitMQ

  • MacOS
  • brew update
  • brew install rabbitmq
  • rabbitmq-server 로 실행

간단하게 실행할 수 있고 실행되면 15672 포트 번호로 들어가고 id, pw 모두 guest 로 하게 되면 들어갈 수 있다.

AMQP 사용해보기

Dependencies 추가

  • Config Server : AMQP for Spring Cloud Bus + Actuator
  • User Microservice , Gateway Service : AMQP for Spring Cloud Bus

application.yml 수정

  • Config Server , user-service , apigateway-service : rabbitmq 의 host , port , username , password 정보 넣기 + actuator 에서 노출 시킬 속정에 busrefresh 추가하기
  rabbitmq:
    host: 127.0.0.1
    port: 5672
    username: guest
    password: guest
    
management:
  endpoints:
    web:
      exposure:
        include: refresh , health , beans , httptrace , busrefresh
  • 위와 같이 각 service 에 rabbitmq 정보를 넣어주고 actuator 에서 busrefresh 도 추가해준다.

Spring Cloud Bus 테스트 해보기

  1. RabbitMQ 서버 기동
  2. discovery server 기동
  3. config-server 기동
  4. 각 MS 기동
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: config-service
  • apigateway-service , user-service 모두 위와 같이 yml 파일을 설정한다.
  • name 을 config-service 라고 하면 config-service 에 있는 application.yml 파일을 읽어온다.
  • user-service 의 로그를 확인해보면 Located property source 부분에 어디서 설정 정보를 불러왔는지 나오는데 config-service 에서 지정한 경로에 있는 application.yml 파일을 가져온다.

POSTMAN 으로 회원가입을 하고 Token 을 가지고 health endpoint 를 호출해보자.

  • 정상적으로 동작한다.
  • 이때 application.yml 에서 token.secret 의 값을 변경했을 때 반영하는 것을 Spring Cloud Bus 를 이용해보자.
http://127.0.0.1:8000/user-service/actuator/busrefresh

POST user-service/actuator/busrefresh 로 호출하면 된다.

  • 아무런 service 에서 호출하면 되고 호출하면 약간의 시간 뒤에 204 성공 코드가 나온다.
  • 그런후 다시 로그인을 하고 해당 Token 을 가지고 확인해보면 변경된 값으로 토큰을 만든것을 확인할 수 있다.
  • 해당 토큰으로 다른 service 를 실행 해봐도 정상적으로 동작한다.
  • 즉 한 번의 refresh 로 모든 service 에 변경사항을 반영했다.

설정 정보의 암호화 처리

대칭키와 비대칭키

Encryption types

  1. Symmetric Encryption : 암호화 , 복호화 할 때 같은 키 값을 사용 (대칭)
  2. Asymmetric Encrpytion : 암호화 , 복호화 할 때 다른 키 값을 사용 (비대칭)

만약 데이터베이스 아이디 , 비밀번호는 중요한 정보이기 때문에 해당 정보들을 암호화해서 저장을 한다.

  • {cipher} 가 붙어있으면 암호화된 상태이다.
  • Spring Cloud COnfig Server 에서 암호화 된 것들을 바꿔서 service 에 보내는 것이다.

config-server 에서 bootstrap.yml 파일에 encrypt:key: 로 암호화할 키를 설정할 수 있다.

  • 그런후에 POSTMAN 에서 POST 8888/encrypt 주소에 Body->Text 에 암호화할 단어를 적으면 응답값이 암호화된 문자열이 나온다.
  • 반대로 해당 암호화된 문자열을 POST 8888/decrypt 로 요청하면 복호화되서 나온다.

Users Microservice 의 applicatino.yml , bootstrap.yml 파일을 수정

  • config-server 의 user-service.yml 로 이동
  • user-service 에 있는 datasource 에 해당하는 정보들을 config-server 에 옮기고 값을 넣을 때 암호화를 해서 넣는다.
  • password 를 암호화 해서 넣을 것인데 이때 위에서 설명한 방식으로 암호화를 시키고 '{cipher}암호화된 문자열' 형식으로 넣어주면 된다.
  • {cipher} 가 있으면 암호화가 된 문자열로 인식한다.
# config-server bootstrap.yml
encrypt:
  key: jiwonjiwonjiwonjiwonjiwon123
  • POSTMAN 에서 8888/encrypt , 8888/decrypt 를 사용해서 암호화 , 복호화를 할 수 있다.

user-service 에서 application.yml 에 있는 datasource: 에 있는 값들을 config-server 에 옮긴다.

# config-server application.yml
spring:
  cloud:
    config:
      server:
        git:
          uri: file:///Users/supportkim/Desktop/git-local-repo
  • user-service의 application.yml 에 있는 datasrouce: 에 값들을 위에 있는 uri 경로에 user-service.yml 를 만들고 여기에 값들을 넣는다.
# user-service bootstrap.yml
spring:
  cloud:
    config:
      uri: http://127.0.0.1:8888
      name: user-service
  • 그런후 user-service 의 bootstrap.yml 에다가 위에 처럼 설정하면 config-server 에 있는 user-service.yml 을 찾고 해당 값을 가지고 datasource 으로 사용할 것이다.

이제 datasource: 값중에서 password 를 암호화해서 넣어보자.

  • 비밀번호를 1234 로 지정했다면 POSTMAN 으로 1234 의 암호화된 값을 가져오고 그 값을 넣어주면 된다.
# config-server 에서 관리하는 user-service.yml
spring:  
  datasource:
   driver-class-name: org.h2.Driver
   url: jdbc:h2:mem:testdb
   username: sa
   password: '{cipher}ad9ccf4ecb3e774ce964725a9012e235e4a22761c3d7cadab01f71b48eab15ef'

이렇게 설정하고 모든 서버를 기동한 후 8888/user-service/default 로 접근해보자.

  • 우리는 yml 파일에 암호화된 pw 를 넣었지만 해당 URI 에 접근하면 1234 로 나오는 것을 확인할 수 있다.
  • user-service 의 포트번호를 알아오고 포트번호/h2-console 로 접근하고 password 를 입력하지 않으면 오류가 발생한다.
  • 이제 여기에 1234 를 넣으면 정상적으로 연결이 된다.

이렇게 암호화된 정보를 설정 파일에 넣고 해당 정보를 복호화해서 사용하는 방법을 알아봤다.

비대칭키를 이용한 암호화 - keytool

  • Public , Private Key 생성 -> JDK keytool 이용
  • keytool 명령어로 만들 수 있다.
  • config-server의 bootstrap.yml 에서 encrypt:key-store: 부분을 넣어주면 비대칭키 암호화를 사용할 수 있다.
  • 위에서 했던 것 처럼 POSTMAN 에서 8888/encrypt 로 요청한 값으로 yml 파일에 password 를 넣으면 된다.
해당 명령어로 jks 파일을 만들 수 있다.
keytool -genkeypair -alias apiEncryptionKey -keyalg RSA -dname "CN=jiwon, 
OU=API Development,O=jiwonkim.co.kr, L=Seoul, C=KR" -keypass "test1234" 
-keystore apiEncryptionKey.jks -storepass "test1234"

해당 명령어로 만든 jks 파일의 내용을 볼 수 있다.
keystore % keytool -list -keystore apiEncryptionKey.jks -v


인증서 파일 만드는 명령어
 keytool -export -alias apiEncryptionKey -keystore apiEncryptionKey.jks -rfc -file trustServer.cer


인증서 파일로 jks 파일 만드는 명령어
keytool -import -alias trustServer -file trustServer.cer -keystore publicKey.jks
  • 해당 예제에서는 첫 번째 명령어만 사용해서 jks 파일을 만들면 된다.
  • 만들 때 파일을 하나 만들어서 그 파일에다가 만들면 된다.
# config-server bootstrap.yml
encrypt:
  key-store:
    location: file://${user.home}/Desktop/keystore/apiEncryptionKey.jks
    password: test1234
    alias: apiEncryptionKey
  • 비대칭키를 이용할 때는 yml 파일을 위와 같이 작성하면 되고 각 정보들은 명령어를 통해 jks 파일을 만들 때 설정한 값들을 넣어주면 된다.
  • 대칭키에서도 했던 것 처럼 8888/encrypt 로 들어가서 암호화를 하고 그 암호화한 값을 user-service.yml 에서 password 에다가 넣어주면 된다.
  • 넣을 때 {cipher} 를 앞에 붙어줘야한다.

여기서는 apigateway-service 의 bootstrap.yml 을 보면 ecommerce.yml 을 읽어오는 것으로 해놨다.

  • ecommerce.yml 에 token 정보가 있고 그 정보를 가져와서 사용을 했었다.
  • 여기서 ecommerce.yml 에 있는 token 정보를 비대칭키 암호화를 해서 넣고 그것을 복호화해서 사용하도록 할 수 있다.
  • ecommerce.yml 에서 token.secret 부분을 8888/encrypt 로 암호화를 하고 그 부분을 {cipher}+암호화된 키 를 넣어주면 된다.

참고자료

profile
덕업일치
post-custom-banner

0개의 댓글