SpringBoot Actuator 안전하게 사용하기

Hyunta·2023년 3월 12일
2
post-custom-banner

SpringBoot Actuator란?

Actuator라는 단어는 생산직군에서 주로 사용되는 단어로 작동장치를 의미합니다. 쉽게 말하면 작은 동작으로 기계를 움직이거나 제어하는데 사용되는 장치를 말합니다.
Actuator는 외부 라이브러리로 의존성을 추가하면 바로 애플리케이션 모니터링 및 관리를 할 수 있습니다.

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-actuator'
}

Actuator는 주로 모니터링의 용도로 사용되고 자주 사용되어지는 엔드포인트로는 health, info, prometheus 등이 있습니다.
이번에 장애 모니터링관련 대시보드를 구성하다 저희 actuator 설정에서 치명적인 보안 이슈를 찾아내고 actuator 설정 부분을 템플릿화 시켜서 컨벤션으로 맞춰간 과정을 소개하려고 합니다.

작동 원리

Actuator에서 제공하는 Endpoints를 사용하려면 두가지 작업을 해야합니다.
첫째는, expose 설정을 통해 노출을 시키는 것이고
둘째는, enable 설정을 통해 활성화 시키는 것입니다.

공식문서를 참고하시면 Actutator에서 제공하는 endpoints들에 상세한 내용을 확인해볼 수 있습니다.

해당 자료를 보면 기본값으로 활성화 된 endpoint와 노출이 된 endPoint를 확인할 수 있습니다.

기본적으로 shutdown 을 제외한 모든 endpoint들은 활성화 되어있습니다.

노출된 endpoint를 확인하기 전에 JMX 방식과 Web 방식 두가지로 endpoint에 접근할 수 있는데, JMX는 Java Management Extension의 약어로 java 1.5버전에 소개되어 외부에서 쉽게 측정할 수 있도록 도와주는 프레임워크입니다.

기본적으로 Web 방식은 health , info 만 노출되어있고 나머지 endpoint는 노출되어있지 않습니다. 반면 JMX 방식은 모든 endPoint가 노출되어 있습니다.

정리하자면 SpringBoot Actuator 의존성을 추가한 뒤 아무 설정도 하지 않았을 경우 Web 방식으로 접근할 수 있는 endPoints는 healthinfo 그리고 JMX 방식으로는 shutdown 을 제외한 모든 endpoint에 접근할 수 있습니다.

Actuator 악용 사례

우선 Actuator를 사용했을 때 발생할 수 있는 악용사례에 대해서 알아보겠습니다.

1. 환경변수로 중요정보를 저장해둔 경우

env endpoint를 노출시켜두면 해당 경로를 통해 현재 사용하고 있는 환경변수 값을 불러올 수 있습니다. 만약 Token secret-key 값이나 DB ID, Password가 있다면 해당 정보를 받아갈 수 있습니다.

2. 중요정보가 메모리에 올라가 있는 경우

서비스 운영 중 사용한 중요 정보가 아직 메모리에 남아있는 경우 heapdump 를 통해 해당 내용을 전부 받아올 수 있습니다.

이런 식으로 웹 애플리케이션의 heapdump 를 받아와서 사용하고 있는 application,yml 정보를 받아올 수 있습니다.

3. shutdown이 enable, expose 한 경우

만약 shutdown이 enable되고 expose된 상황이라면 임의로 웹 애플리케이션을 중지시킬수 있습니다.

Actuator를 안전하게 사용하는 방법

# Actuator 보안 설정 샘플

# 1. 활성화 상태를 기본값으로 false로 만들고, 필요한 endpoint를 enable해서 사용한다.
management.endpoints.enabled-by-default = false

management.endpoint.info.enabled = true
management.endpoint.health.enabled = true

# 2. 필요한 endpoint만 노출해서 사용한다.
management.endpoints.jmx.exposure.exclude = *
management.endpoints.web.exposure.include = info, health

# 3. 애플리케이션과 다른 포트 번호를 사용한다.
management.server.port = [포트번호]

# 4. actuator의 경로를 변경한다.
management.endpoints.web.base-path = [/변경된 경로]

1. 활성화 상태의 기본값을 모두 false로 변경한다.

기본값으로 모든 endpoint는 활성화 되어있습니다. 이럴 경우 필요하지 않은 endpoint에 대해서도 enable 되어있기 때문에 빈으로 생성됩니다. 반대로 모든 값을 비활성화하고 필요한 endpoint만 활성화해서 사용합니다.

2. 필요한 endpoint만 노출해서 사용한다.

JMX를 사용하는 환경이 아니라면 해당 방식에 대한 접근을 모두 제거합니다. web에서도 필요한 endpoint만 활성화해서 하나씩 사용합니다. 하나 주의할 점은 exclude가 include보다 우위를 갖기 때문에 노출을 시킬 endpoint는 exclude에 작성하면 안됩니다.

3. 애플리케이션과 다른 port를 사용한다.

기본적으로 actuator는 애플리케이션과 동일한 port를 사용합니다. 해당 port를 변경하게 되면 외부에서 함부로 접근할 수 없습니다.

4. actuator의 경로를 변경한다

기본 설정은 /actuator/{endpoint} 처럼 actuator의 경로로 설정됩니다. 해당 부분을 변경하면 외부에서 아무나 접근할 수 없습니다.

정리

  • 모니터링을 위해 설정한 actuator를 잘 알고 사용하지 않으면 중요한 정보를 노출 시킬 수 있습니다.
  • 망이 분리되어있다면 접근할 수 없겠지만, 그래도 보안은 다다익선이므로 신경써서 관리하면 좋을 것 같습니다.

Reference

https://techblog.woowahan.com/9232/
https://www.baeldung.com/java-management-extensions

profile
세상을 아름답게!
post-custom-banner

0개의 댓글