배포 환경에서 PostgreSQL 로그를 확인하면 모든 접속이 서버 IP로만 기록되는 문제가 발생했습니다.
# 로컬 환경
2026-02-10 10:00:00 [12345] 192.168.0.49 mydb ✅ 실제 클라이언트 IP
# 배포 환경
2026-02-10 10:00:00 [12345] 192.168.0.111 mydb ❌ 서버 IP만 표시
클라이언트 (192.168.0.49)
↓
웹서버/프록시 (192.168.0.111)
↓
PostgreSQL → client_addr = 192.168.0.111 (웹서버 IP만 보임)
PostgreSQL은 직접 연결된 클라이언트 IP만 인식하기 때문에 프록시 환경에서는 서버 IP만 기록됩니다.
PostgreSQL의 application_name에 실제 클라이언트 IP를 저장하는 방식으로 해결했습니다.
DatabaseClientIpInterceptor.java
@Slf4j
@Component
@RequiredArgsConstructor
public class DatabaseClientIpInterceptor implements HandlerInterceptor {
private final DataSource dataSource;
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) {
try {
// HTTP 헤더에서 실제 클라이언트 IP 추출
String clientIp = IpAddrHelper.getClientIpAddr(request);
// PostgreSQL에 application_name 설정
try (Connection conn = dataSource.getConnection();
Statement stmt = conn.createStatement()) {
String appName = "myapp_" + clientIp.replace("'", "");
stmt.execute("SET application_name TO '" + appName + "'");
log.debug("Set PostgreSQL application_name to: {}", appName);
}
} catch (Throwable e) {
log.warn("Failed to set client IP (ignored): {}", e.getMessage());
}
return true;
}
}
@Override
public void addInterceptors(InterceptorRegistry registry) {
~ 기존로직 ~
// DB IP Interceptor 추가
registry.addInterceptor(databaseClientIpInterceptor)
.addPathPatterns("/**")
.excludePathPatterns(excludes);
}
postgresql.conf
log_line_prefix = '%m [%p] %h %d @%a '
%m: 타임스탬프%p: 프로세스 ID%h: 클라이언트 IP (서버 IP로 표시됨)%d: 데이터베이스명%a: application_name (실제 클라이언트 IP 표시) ✅1. 클라이언트 요청 (192.168.0.49)
↓
2. DatabaseClientIpInterceptor 실행
- X-Forwarded-For 헤더에서 실제 IP 추출
- SET application_name TO 'myapp_192.168.0.49' 실행
↓
3. Controller 실행
- DB 쿼리: SELECT * FROM users
↓
4. PostgreSQL 로그 기록
- "2026-02-10 10:00:00 [12345] 192.168.0.111 mydb @myapp_192.168.0.49"
변경 전:
2026-02-10 10:00:00 [12345] 192.168.0.111 mydb SELECT * FROM users
2026-02-10 10:00:01 [12346] 192.168.0.111 mydb SELECT * FROM orders
변경 후:
2026-02-10 10:00:00 [12345] 192.168.0.111 mydb @myapp_192.168.0.49 SELECT * FROM users
2026-02-10 10:00:01 [12346] 192.168.0.111 mydb @myapp_192.168.0.52 SELECT * FROM orders
이제 @myapp_ 뒤에 각 클라이언트의 실제 IP가 기록되어 사용자별 추적이 가능합니다.
프록시 환경에서 PostgreSQL 로그에 실제 클라이언트 IP를 남기는 방법을 Spring Interceptor와 application_name을 활용해 구현했습니다. 이를 통해 사용자별 DB 접근 추적과 보안 감사가 가능해졌습니다.