보안 로깅(Security Logging) : 애플리케이션에서 발생하는 다양한 이벤트(로그인 시도, 데이터 접근, 오류 등)를 기록하는 과정입니다. 이를 통해 누가, 언제, 어떤 행동을 했는지 추적할 수 있습니다
보안 모니터링(Security Monitoring) : 기록된 로그를 실시간 또는 주기적으로 분석하여 의심스러운 활동이나 보안 위협을 탐지하고 대응하는 과정입니다.
a. 로깅 프레임워크 사용
Java와 Spring에서는 다양한 로깅 프레임워크를 사용할 수 있습니다.
<configuration>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logs/app.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
</root>
</configuration>
b. Spring Security와 통합
Spring Security는 인증과 인가를 관리하며, 보안 관련 이벤트를 로깅할 수 있습니다.
import org.springframework.security.authentication.event.AuthenticationSuccessEvent;
import org.springframework.security.authentication.event.AuthenticationFailureBadCredentialsEvent;
import org.springframework.context.event.EventListener;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Component
public class SecurityEventListener {
private static final Logger logger = LoggerFactory.getLogger(SecurityEventListener.class);
@EventListener
public void handleAuthenticationSuccess(AuthenticationSuccessEvent event) {
logger.info("사용자 {}가 성공적으로 로그인했습니다.", event.getAuthentication().getName());
}
@EventListener
public void handleAuthenticationFailure(AuthenticationFailureBadCredentialsEvent event) {
logger.warn("사용자 {}의 로그인 시도가 실패했습니다.", event.getAuthentication().getName());
}
}
c. AOP를 이용한 로깅
AOP(Aspect-Oriented Programming)를 사용하면 특정 메서드 호출시 자동으로 로깅을 추가할 수 있습니다.
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
@Aspect
@Component
public class LoggingAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
logger.info("메서드 호출: " + joinPoint.getSignature().getName());
}
}
d. 외부 모니터링 도구와 연동
로그를 중앙에서 관리하고 분석하기 위해 ELK Stack, Prometheus, Grafana 같은 도구를 사용할 수 있습니다.
e. 로그 보안 관리
로그는 민감한 정보를 포함할 수 있으므로 안전하게 저장하고 접근을 제어해야 합니다.
물론입니다! 취업 준비 중인 신입 Java/Spring 백엔드 개발자로서 보안 로깅 및 모니터링을 실습할 수 있는 몇 가지 프로젝트와 연습 과제를 제안드릴게요. 이러한 실습을 통해 실제 현장에서 요구되는 기술을 익히고 포트폴리오에 추가할 수 있습니다.
Spring Boot 애플리케이션에 로깅 프레임워크(SLF4J + Logback)를 설정하고 다양한 로그 레벨을 활용해보기.
Spring Boot 프로젝트 생성:
Spring Web, Spring Security(추후 사용).로깅 설정:
src/main/resources 디렉토리에 logback-spring.xml 파일을 생성합니다.로그 사용 예제 작성:
Logger를 주입하고 다양한 로그 레벨(DEBUG, INFO, WARN, ERROR)을 사용하여 로그 메시지를 출력해보세요.import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class SampleController {
private static final Logger logger = LoggerFactory.getLogger(SampleController.class);
@GetMapping("/test")
public String testLogging() {
logger.debug("디버그 로그 메시지");
logger.info("정보 로그 메시지");
logger.warn("경고 로그 메시지");
logger.error("에러 로그 메시지");
return "로그 테스트 완료";
}
}
로그 파일 확인:
logs/app.log 파일을 열어 로그 메시지가 제대로 기록되는지 확인하세요.Spring Security를 설정하고 로그인 성공 및 실패 이벤트를 로깅하여 보안 관련 활동을 추적해보기.
Spring Security 설정:
Spring Security 의존성을 추가하고 기본 보안 설정을 구성하세요.import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
@Configuration
@EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
@Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.inMemoryAuthentication()
.withUser("user").password("{noop}password").roles("USER");
}
@Override
protected void configure(HttpSecurity http) throws Exception {
http
.authorizeRequests()
.anyRequest().authenticated()
.and()
.formLogin()
.permitAll()
.and()
.logout()
.permitAll();
}
}
보안 이벤트 리스너 작성:
SecurityEventListener 클래스를 추가하여 로그인 성공 및 실패 이벤트를 로깅하세요.테스트:
logs/app.log 파일에서 로그인 성공 및 실패 로그가 기록되는지 확인합니다.AOP(Aspect-Oriented Programming)를 사용하여 특정 패키지의 모든 서비스 메서드 호출 시 로그를 자동으로 기록해보기.
AOP 의존성 추가:
spring-boot-starter-aop 의존성을 pom.xml에 추가하세요.<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
LoggingAspect 클래스 작성:
LoggingAspect 클래스를 생성하고 원하는 패키지에 맞게 포인트컷을 수정하세요.@Aspect
@Component
public class LoggingAspect {
private Logger logger = LoggerFactory.getLogger(this.getClass());
@Before("execution(* com.example.service.*.*(..))")
public void logBefore(JoinPoint joinPoint) {
logger.info("메서드 호출: " + joinPoint.getSignature().getName());
}
}
서비스 클래스 작성:
com.example.service 패키지에 간단한 서비스 클래스를 작성하고 메서드를 호출해보세요.테스트:
ELK Stack(Elasticsearch, Logstash, Kibana)을 사용하여 로그를 중앙에서 수집, 저장, 시각화해보기.
ELK Stack 설치:
Logstash 설정:
logstash.conf 파일을 생성하여 Logstash가 Spring Boot 애플리케이션의 로그를 수집하도록 설정합니다.input {
tcp {
port => 5044
codec => json
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "spring-logs-%{+YYYY.MM.dd}"
}
stdout { codec => rubydebug }
}
Spring Boot에 Logstash Appender 추가:
logback-spring.xml 파일에 Logstash Appender를 추가합니다.<appender name="LOGSTASH" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>localhost:5044</destination>
<encoder class="net.logstash.logback.encoder.LogstashEncoder" />
</appender>
<root level="INFO">
<appender-ref ref="FILE" />
<appender-ref ref="LOGSTASH" />
</root>
Kibana에서 로그 시각화:
테스트:
Prometheus와 Grafana를 사용하여 애플리케이션의 메트릭을 수집하고 시각화해보기.
Prometheus와 Grafana 설치:
Spring Boot 애플리케이션에 Micrometer 추가:
spring-boot-starter-actuator와 micrometer-registry-prometheus 의존성을 pom.xml에 추가합니다.<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>io.micrometer</groupId>
<artifactId>micrometer-registry-prometheus</artifactId>
</dependency>
애플리케이션 설정:
application.properties 파일에 Prometheus 엔드포인트를 활성화합니다.management.endpoints.web.exposure.include=health,info,prometheus
Prometheus 설정:
prometheus.yml 파일을 수정하여 Spring Boot 애플리케이션의 Prometheus 엔드포인트를 스크랩하도록 설정합니다.scrape_configs:
- job_name: 'spring-boot-app'
metrics_path: '/actuator/prometheus'
static_configs:
- targets: ['localhost:8080']
Grafana 대시보드 구성:
테스트:
로그에 포함되는 민감한 정보를 보호하고 로그 파일의 접근을 제어해보기.
민감 정보 필터링:
로그 암호화:
Encoder를 커스터마이징하여 로그 메시지를 암호화할 수 있습니다.접근 제어 설정:
chmod와 chown 명령어를 사용하여 로그 파일의 권한을 설정합니다.로그 정리 및 보관:
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>logs/app.%d{yyyy-MM-dd}.log.gz</fileNamePattern>
<maxHistory>30</maxHistory>
<totalSizeCap>3GB</totalSizeCap>
</rollingPolicy>
의심스러운 활동이 감지되었을 때 실시간으로 알림을 받을 수 있도록 설정해보기.
Elasticsearch Watcher 또는 Kibana Alerts 사용:
Slack 또는 이메일과 연동:
테스트:
기능:
기술 스택:
구현 단계:
완성 후 포트폴리오에 포함할 내용:
위의 실습 과제를 통해 보안 로깅 및 모니터링에 대한 이해를 심화하고, 실제 프로젝트에 적용할 수 있는 경험을 쌓을 수 있습니다. 이러한 프로젝트는 취업 시 포트폴리오로 활용하기에도 매우 유용하며, 면접에서 실무 능력을 어필하는 데 큰 도움이 될 것입니다. 실습 중 어려운 점이나 추가적인 질문이 있다면 언제든지 문의해주세요!