RECENT POSTS

최근에 작성한 글

01 / 03

전체 글

전체 보기

[TIL] 모니터링 시스템 및 시큐어 코딩

1. 모니터링의 중요성

  • 시스템의 성능, 가용성, 안정성을 지속적으로 감시하고 잠재적인 문제를 신속하게 발견하여 대응할 수 있게 해줌.
  • 성능 병목 현상이나 리소스 낭비를 식별하고 해결하여 시스템의 전체적인 효율성을 높일 수 있음.
  • 로그 분석을 통해 시스템의 이상 징후를 조기에 발견하고 문제의 원인을 정확히 파악할 수 있음.

1. 모니터링이란?

시스템의 성능, 안정성 및 가용성을 실시간으로 관찰하고 측정하는 과정

2. 모니터링 중요성

  1. 문제 예방 : 잠재적인 문제를 사전에 발견하고 해결
  2. 빠른 대응 : 문제가 발생했을 때 신속하게 대응할 수 있음
  3. 성능 최적화 : 성능 병목 지점을 찾아 개선
  4. 사용자 경험 향상 : 안정적이고 빠른 서비스를 제공하여 사용자 만족도 높임
  5. 비즈니스 연속성 : 비즈니스 운영의 연속성을 유지

3. 모니터링 범위

  1. 서버 모니터링 : CPU, 메모리, 디스크 사용량, 네트워크 트래픽 등 서버 자원 사용을 모니터링합니다.
  2. 애플리케이션 모니터링 : 애플리케이션의 상태, 성능, 로그 등을 모니터링합니다.
  3. 네트워크 모니터링 : 네트워크 트래픽, 대역폭 사용량, 네트워크 지연 등을 모니터링합니다.
  4. 데이터베이스 모니터링 : 쿼리 성능, 연결 수, 데이터베이스 사용량 등을 모니터링합니다.
  5. 보안 모니터링 : 보안 이벤트, 침입 시도, 취약점 등을 모니터링합니다.

4. Spring Boot Actuator

Spring Boot 애플리케이션의 상태와 성능을 모니터링하고 관리할 수 있도록 다양한 엔드포인트를 제공하는 기능
Actuator는 헬스 체크, 메트릭스, 환경 정보, 로그 정보 등 여러 가지 중요한 정보를 쉽게 확인할 수 있도록 도와줌

# Actuator 앤드포인트

/actuator/health: 애플리케이션의 상태를 확인합니다.
/actuator/metrics: 애플리케이션의 메트릭 정보를 제공합니다.
/actuator/loggers: 로깅 설정을 조회하고 변경할 수 있습니다.
/actuator/env: 환경 변수와 설정 정보를 확인합니다.
/actuator/beans: 애플리케이션 컨텍스트에 있는 빈 목록을 확인합니다.
/actuator/threaddump: 스레드 덤프를 확인합니다.
/actuator/httptrace: 최근 HTTP 요청 및 응답을 추적합니다.

주의 사항

  • 보안 : 필요한 엔드포인트만 노출하는 것을 권장
  • 앤드포인트 보호 : Actuator 포트만 다른 포트로 설정

5. Prometheus

오픈소스 시스템 모니터링 및 경고 도구
시계열 데이터베이스를 사용하여 메트릭 데이터를 수집하고 쿼리 및 시각화를 통해 시스템 상태를 모니터링하고 경고를 설정

# 구성 요소

Prometheus 서버:
메트릭 데이터를 수집하고 저장하는 핵심 컴포넌트 
각 타겟으로부터 데이터를 주기적으로 스크랩(scrape)하여 시계열 데이터베이스에 저장
시계열 데이터베이스(Time Series Database, TSDB)는 시간에 따라 변화하는 데이터를 효율적으로 저장하고 조회할 수 있도록 최적화된 데이터베이스

Exporters:
Prometheus는 기본적으로 애플리케이션에서 메트릭 데이터를 수집
Exporter는 특정 애플리케이션이나 시스템의 메트릭 데이터를 Prometheus가 이해할 수 있는 형식으로 변환해주는 도구
예시: Node Exporter (서버의 시스템 메트릭 수집), PostgreSQL Exporter (PostgreSQL 메트릭 수집), Spring boot의 micrometer-registry-prometheus 디펜던시

Pushgateway:
짧은 수명의 작업(job)에서 메트릭을 수집하여 Prometheus 서버에 푸시(push)할 수 있음
일반적으로 지속적으로 실행되지 않는 작업에서 사용 예를 들어 배치 작업, 스크립트 실행, 크론 작업 등

Alertmanager:
Prometheus 서버에서 발생하는 경고(alert)를 처리하고, 이메일, PagerDuty, Slack 등 다양한 방법으로 알림을 보낼 수 있음

Grafana:
Prometheus 데이터를 시각화하기 위해 자주 사용되는 대시보드 도구
Grafana를 사용하면 Prometheus에서 수집한 메트릭 데이터를 대시보드 형태로 시각화할 수 있음

6. Grafana

오픈소스 데이터 시각화 및 모니터링 도구
대시보드를 생성하고, 데이터를 그래프나 차트 형태로 표현하며, 알림 기능을 제공하여 모니터링을 강화할 수 있음

#주요 기능

대시보드 생성:
Grafana는 사용자가 데이터를 시각화할 수 있는 대시보드를 생성할 수 있음
여러 가지 그래프, 차트, 게이지 등을 사용하여 데이터를 시각적으로 표현할 수 있음

다양한 데이터 소스 지원:
Prometheus, InfluxDB, Graphite, Elasticsearch, MySQL, PostgreSQL 등 다양한 데이터 소스를 지원
이를 통해 여러 시스템과 애플리케이션의 데이터를 통합하여 시각화할 수 있음

알림 기능:
조건을 설정하여 조건이 충족되면 이메일, Slack, PagerDuty 등 다양한 채널을 통해 알림을 보낼 수 있음
이를 통해 시스템 상태를 실시간으로 모니터링하고 문제가 발생했을 때 즉시 대응할 수 있음

플러그인 지원:
Grafana는 플러그인 아키텍처를 지원하여, 다양한 플러그인을 통해 기능을 확장할 수 있습니다. 예를 들어, 새로운 데이터 소스나 시각화 유형을 추가할 수 있음

사용자 관리:
사용자를 관리하고, 대시보드와 데이터 소스에 대한 접근 권한을 설정할 수 있음
이를 통해 팀 내에서 협업을 강화하고 데이터 보안을 유지할 수 있음

7. 애플리케이션 로그 모니터링

1. Loki
Grafana Labs에서 개발한 로그 집계 시스템
로그 데이터를 저장하고 Grafana를 통해 시각화하는 데 사용

 

2. Loki-logback-appender
Logback을 사용하는 Java 애플리케이션에서 로그를 Loki로 직접 전송하기 위한 라이브러리
별도의 Promtail 설정 없이도 로그를 Loki로 전송할 수 있음

2. 보안

  • 보안 위협으로부터 애플리케이션을 보호하기 위해 강력한 인증 및 권한 부여 매커니즘을 구현해야 함.
  • 정기적인 보안 점검 및 취약성 테스트 => 보안 상태 평가

1. CORS

한 출처에서 실행 중인 웹 애플리케이션이 다른 출처의 리소스에 접근할 수 있도록 브라우저에서 제공하는 보안 기능
동일 출처 정책에 따라 동작하며 다른 출처의 리소스 접근을 제한

 

필요성

  1. API 호출 : 클라이언트 중심의 웹 애플리케이션은 종종 다른 도메인에서 호스팅되는 API를 호출해야 함.
  2. 리소스 공유 : 여러 도메인 간의 이미지, 스타일시트, 스크립트, 폰트 등의 리소스를 공유
#동작 원리
브라우저는 다른 출처(Origin)로 요청을 보낼 때 서버의 CORS 정책을 확인하여 요청을 허용할지 판단한다.

1. Simple Request

조건을 만족하는 단순 요청은 Preflight 없이 바로 실제 요청을 전송한다.

GET, HEAD, POST 중 하나
허용된 헤더만 사용
Content-Type이 application/x-www-form-urlencoded, multipart/form-data, text/plain 중 하나
Browser → Server : 실제 요청
Browser ← Server : CORS 관련 헤더와 응답

브라우저는 응답의 Access-Control-Allow-Origin 등을 확인하여 응답을 사용할 수 있는지 판단한다.

2. Preflight Request

단순 요청의 조건을 만족하지 않는 경우 브라우저가 실제 요청을 보내기 전에 해당 요청을 서버가 허용하는지 확인하는 과정이다.

Browser → Server : OPTIONS (Preflight)
Browser ← Server : 허용 Origin, Method, Header


            ↓ 허용된 경우


Browser → Server : 실제 요청
Browser ← Server : 응답

예를 들어 PUT, DELETE를 사용하거나 application/json, 커스텀 헤더 등을 사용하는 경우 Preflight가 발생할 수 있다.

서버는 다음과 같은 헤더를 통해 허용 범위를 알려준다.

Access-Control-Allow-Origin : 허용할 Origin
Access-Control-Allow-Methods : 허용할 HTTP Method
Access-Control-Allow-Headers : 허용할 Header

 

주의사항

  1. 보안 고려사항 :
    신뢰할 수 없는 출처는 허용하지 않도록 주의
  2. 성능 고려사항 :
    Preflight 요청이 빈번하면 성능이 저하 -> Access-Control-Max-Age 를 설정하여 Preflight 요청을 캐싱
    불필요한 Preflight 요청을 최소화하기 위해 단순 요청 조건을 충족하도록 API 설계를 검토.

2. CSRF

웹 애플리케이션의 취약점을 이용해 사용자가 의도하지 않은 요청을 보내는 공격 기법

 

방지 방법

  1. Referer 헤더 검증 :
    요청의 Referer 헤더를 확인하여 요청이 신뢰할 수 있는 출처에서 온 것인지 확인할 수 있음
    Referer 헤더는 사용자가 조작할 수 있고, 일부 브라우저에서는 이 헤더를 포함하지 않을 수 있음
  2. CSRF 토큰 사용 :
    가서버는 각 요청에 대해 고유한 토큰을 생성하고, 이를 폼에 포함 => 서버는 요청이 들어올 때 이 토큰을 검증
  3. form 대신 API사용 :
    API를 통해 JSON데이터로 통신한다면 해당 이슈를 피할 수 있음.

3. XSS

악성 스크립트를 다른 사용자의 브라우저에서 실행시키는 공격

 

공격 종류

  1. 반사형 XSS : URL 등의 사용자 입력에 포함된 악성 스크립트가 서버 응답에 그대로 포함되어 실행
  2. 저장형 XSS : 게시글 등에 악성 스크립트를 저장하고 다른 사용자가 해당 데이터를 조회할 때 실행
  3. DOM 기반 XSS : 클라이언트의 JavaScript가 사용자 입력을 DOM에 삽입하는 과정에서 악성 스크립트가 실행

방지 방법

  1. 입력값 검증 및 출력 시 인코딩을 통해 사용자 입력이 스크립트로 실행되지 않도록 처리
  2. CSP(Content Security Policy)를 설정하여 실행 가능한 스크립트의 출처를 제한
  3. 쿠키에 HttpOnly 속성을 적용하여 JavaScript를 통한 쿠키 접근 및 탈취 방지

응, 똑같이 정의 → 위험성 → 방지 방법 정도만 남기면 돼.

4. SQL Injection

사용자 입력값에 악의적인 SQL을 삽입하여 데이터베이스의 쿼리를 조작하는 공격

# 예시
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

public class SqlInjectionExample {
    public static void main(String[] args) {
        String username = "admin'; --";
        String password = "password";
        String query = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";

        try (Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testdb", "root", "password");
             Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(query)) {

            if (rs.next()) {
                System.out.println("User authenticated");
            } else {
                System.out.println("Authentication failed");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

위험성

  1. 데이터 탈취 : DB에 저장된 개인정보 등 민감한 데이터를 조회
  2. 데이터 변조 : 데이터를 임의로 수정하거나 삭제
  3. 인증 우회 및 권한 상승 : 쿼리를 조작하여 인증 절차를 우회하거나 높은 권한 획득

방지 방법

  1. Prepared Statement : 사용자 입력을 SQL문에 직접 연결하지 않고 파라미터로 전달
  2. ORM 사용 : Hibernate 등의 ORM에서 파라미터 바인딩을 사용하여 안전하게 쿼리 실행
  3. 입력값 검증 : 허용된 형식의 입력인지 검증하고 사용자 입력으로 SQL문을 직접 생성하지 않음
  4. 최소 권한 원칙 : DB 계정에 필요한 최소한의 권한만 부여하여 공격 발생 시 피해 범위를 제한

5. 그 외 보안 문제

  1. Open Redirect
    사용자가 입력한 URL을 검증하지 않고 리다이렉트하여 악성 사이트로 이동시키는 공격
    → 허용된 URL만 사용하거나 리다이렉트 URL을 검증하여 방지
  2. Directory Traversal
    ../등의 경로를 이용하여 서버에서 허용되지 않은 파일이나 디렉터리에 접근하는 공격
    → 접근 가능한 경로 및 파일을 제한하고 입력된 파일 경로를 검증
  3. Clickjacking
    투명한 iframe 등을 이용하여 사용자가 의도하지 않은 버튼이나 링크를 클릭하도록 유도하는 공격
    → X-Frame-Options, CSP 등을 이용하여 외부 페이지의 iframe 삽입을 제한
  4. Sensitive Data Exposure
    비밀번호, 개인정보 등의 민감한 데이터가 적절히 보호되지 않아 노출되는 보안 문제
    → HTTPS 사용, 데이터 암호화, 접근 권한 제한 등을 통해 방지
  5. Insecure Deserialization
    신뢰할 수 없는 데이터를 역직렬화하면서 악의적으로 조작된 객체가 처리되는 취약점
    → 역직렬화할 데이터와 타입을 검증하고 신뢰할 수 없는 객체의 역직렬화를 제한
  6. Insufficient Logging & Monitoring
    로그 기록이나 모니터링이 부족하여 공격이나 이상 행동을 빠르게 발견하지 못하는 문제
    → 주요 이벤트를 로깅하고 지속적인 모니터링 및 로그 검토 수행
  7. CVE / CVSS

CVE : 공개된 보안 취약점을 식별하기 위한 고유 번호 체계
CVSS : 취약점의 심각도를 0~10점으로 평가하는 점수 체계

  1. Log4j 취약점 (Log4Shell)
    Java 로깅 라이브러리 Log4j에서 발견된 심각한 취약점(CVE-2021-44228)으로, 광범위한 Java 애플리케이션에 영향을 준 사례
    → 취약한 라이브러리를 최신 버전으로 업데이트하고 지속적인 보안 패치 및 모니터링 필요