개요
보안 시스템에서 수집되는 악성 URL들은 다양한 형태로 존재하며, 이들을 정규화하고 중복 제거하는 과정은 분석의 정확성과 효율성을 위해 필수적입니다. 이를 위해 Java의 HashSet<URL>을 활용해 중복을 제거하는 구조로 구성이 되어 있었지만, 예상치 못한 DNS 트래픽이 내부망에서 발생하는 문제가 나타났습니다.
단순히 중복이 제대로 제거되지 않는 수준이 아니라, 각 URL 객체 생성 시마다 DNS 쿼리가 자동 발생하며 내부 DNS 서버에 부하를 주는 현상이 발생한 것이죠. 이 글에서는 해당 현상의 원인과 실제 네트워크 패킷 분석을 통해 검증한 과정, 그리고 최종적으로 적용한 해결 방안을 공유합니다.
현상: 내부망 DNS 트래픽 급증
보안 로그 처리 중, 내부 DNS 서버에 반복적으로 DNS 쿼리가 찍히는 현상이 포착되었습니다.
트래픽 양상과 요청 IP를 추적한 결과, 바로 URL 정규화 및 중복 제거 로직에서 문제가 발생하고 있었습니다.
의심 로직 요약:
Set<URL> maliciousUrlSet = new HashSet<>();
for (String rawUrl : extractedUrls) {
URL url = new URL(rawUrl);
maliciousUrlSet.add(url); // 내부적으로 DNS 요청 발생
}
→ 예상과 달리, new URL()을 통해 객체를 생성하고 HashSet에 추가하는 과정에서 내부 DNS 쿼리 요청이 다수 발생
→ 심지어 동일 도메인이라도 IP 응답이 다르면 중복으로 인식되지 않아 비정상적인 중복 저장까지 발생
원인: URL 클래스의 equals() 및 hashCode() 동작 방식
Java의 URL 클래스는 equals()와 hashCode() 구현 시 내부적으로 다음과 같은 비교 방식을 따릅니다:
두 URL의 프로토콜, 포트, 경로 등이 같더라도, 호스트명이 IP로 해석된 결과가 다르면 동일하지 않다고 판단
즉, HashSet<URL>을 사용할 경우:
- URL을 추가할 때마다 equals() / hashCode() 호출 → 자동으로 호스트명을 IP로 변환하기 위해 DNS 쿼리 발생
- 결과적으로 내부망에서는 불필요한 외부 DNS 질의가 대량 발생하고, 동일 도메인이라도 IP가 다르면 중복으로 처리되지 않음
검증: tcpdump를 이용한 실제 패킷 캡처
문제를 재현하고 DNS 요청이 정말 발생하는지 검증하기 위해, 테스트 환경에서 tcpdump를 활용해 패킷을 분석했습니다.
sudo tcpdump -i any port 53 and '(udp or tcp)' -nn
sudo tcpdump -i any udp port 53 and dst host 8.8.8.8
→ 위 명령어로 URL 객체 생성 시점에 DNS 요청이 발생하는 것을 직접 캡처하여 시각적으로 확인
→ 동일한 도메인에 대해서도 반복적으로 쿼리 요청이 발생함을 확인 (IP TTL 또는 로컬 DNS 캐시의 영향과 무관)
해결: 문자열 기반 정규화 및 비교 방식으로 전환
내부망 DNS 부하 문제와 URL 중복 제거 정확도를 동시에 해결하기 위해, URL 객체 대신 문자열 기반 처리 방식으로 로직을 수정했습니다.
개선된 로직:
Set<String> normalizedUrlSet = new HashSet<>();
for (String rawUrl : extractedUrls) {
try { URI uri = new URI(rawUrl);
String normalized = uri.toString();
normalizedUrlSet.add(normalized);
} catch (URISyntaxException e) {
// 무효한 URL은 무시
}
}
- 문자열 기반으로 중복 제거 → DNS 해석 생략
- 결과적으로 내부망 트래픽 완전히 제거, 중복 처리도 도메인 중심으로 일관성 있게 적용 가능
TMI
DNS쿼리 시 기본적으로 UDP로 통신을 진행하지만 상황에따라 TCP로도 동작을 한다.
기본 용도 | 대부분의 DNS 질의 (빠름) | 응답이 클 때만 사용 (512B 초과) |
장점 | 빠르고 가볍다 | 큰 데이터 처리 가능 |
단점 | 512바이트 제한, 무결성 확인 어려움 | 느리고 연결 비용 발생 |
전환 조건 | TC=1 (응답 잘림) | 클라이언트가 재전송 시 자동 전환 |
마무리
이번 경험은 단순한 URL 중복 제거 로직이 네트워크 인프라에도 영향을 줄 수 있다는 것을 실제로 체감한 사례였습니다. Java 기본 라이브러리의 내부 동작 방식까지 이해하고, 실제 패킷 분석을 통해 문제를 검증하고 해결한 이 경험은 보안 로직의 신뢰성과 안정성을 높이는 데 큰 도움이 되었습니다.
비슷한 환경에서 URL 처리 및 중복 제거를 고민하는 분들에게 작은 참고가 되길 바랍니다.
'JAVA' 카테고리의 다른 글
Bean 충돌 없는 멀티모듈 구성, 이렇게 설계했습니다 (1) | 2025.06.26 |
---|---|
Effective java 정복기 6장 (0) | 2025.03.15 |
Reactor Netty HTTP Client Connection (0) | 2025.02.06 |
Effective java 정복기 4장 (0) | 2025.01.09 |
Effective java 정복기 3장 (1) | 2025.01.06 |