- Published on
CNAME 기능 구현을 통한 개인적인 정리
- Authors
- Name
- 김민석
Introduction
상황
DNS
와 CNAME
레코드의 개념을 학습하면서 이를 직접 Java
와 Spring
으로 구현해보고 싶었다. 특히 도메인의 CNAME 레코드를 조회하는 기능을 개발해보는 것을 목표로 삼았다. 이를 통해 DNS 레코드 처리 방식과 네트워크 통신 흐름을 이해하고, 실전 개발 능력을 키우고자 한다.
문제

프로젝트를 시작하면서 CNAME 레코드 조회 기능을 구현하는 과정에서 몇 가지 어려움에 직면했다.
첫째
CNAME 레코드 구현 경험 부족이었다.
DNS의 CNAME 레코드를 어떻게 조회하고 처리해야 할지에 대한 개념과 경험이 부족했기 때문에, 기능을 구체적으로 어떻게 구현할지 명확한 방향이 잡히지 않았다.
둘째
조회 실패 시 원인 파악의 어려움이 있었다.
초기 테스트를 진행할 때 특정 도메인으로 CNAME 조회를 실행했지만, 결과로null
값이 반환되었고, 원인이 무엇인지 바로 파악할 수 없었다. 실패가 도메인 자체의 문제인지 코드 로직의 오류인지 명확히 확인할 필요가 있었다.
마지막으로, DNS 응답 처리 구조에 대한 이해 부족이었다.
단순히 조회만 하는 것을 넘어서, 조회된 데이터를 사용자에게 어떤 형태로 반환할지, 예외 상황에서는 어떻게 처리할지에 대해 고민해야 했다. 이 과정에서 데이터를 명확하게 구조화하고 응답 형태를 설계하는 부분이 도전 과제가 되었다.
이런 문제들을 해결하기 위해 단계적으로 원인을 분석하고, DNS 조회 기능을 구체적으로 구현하며 개선해 나갔다.
CNAME 기능 구현
- Java와 Spring을 활용해 CNAME 레코드 조회 기능을 직접 구현하였다.
- 이를 통해 사용자가 입력한 도메인의 DNS 서버와 통신하여 CNAME 레코드를 확인하고, 그 결과를 API 형태로 반환할 수 있는 기능을 개발했다. 이 과정에서
DNSJava 라이브러리
를 사용해 DNS 서버와의 통신을 처리하였고, Spring Boot를 통해 사용자 API를 제공할 수 있도록 설계했다.
기능 상세 설명
도메인 입력 및 CNAME 조회
- 사용자가 API에 도메인 이름을 입력하면, 해당 도메인의 CNAME 레코드를 조회한다.
- 예를 들어, 사용자가
"www.google.com"
을 입력하면, 해당 도메인의 CNAME 정보를 DNS 서버로부터 요청한다.
조회 결과 반환
- 조회된 결과는
alias
(별칭)와target
(실제 대상)의 형태로 반환 된다.
{ "alias": "www.google.com.", "target": "google.com.", "message": "CNAME record found successfully" }
- 조회된 결과는
조회 실패 및 오류 처리
- CNAME 레코드가 없는 도메인이나 잘못된 요청의 경우, 명확한 메시지를 반환한다.
{ "alias": null, "target": null, "message": "CNAME record not found" }
- 예외 상황이 발생했을 경우, 해당 에러 메시지를 API를 통해 반환한다.
{ "alias": null, "target": null, "message": "Error: [오류 내용]" }
구현의 핵심 구성 요소
- DnsController.java
역할:
사용자 요청을 처리하고, DnsService를 호출해 결과를 반환한다.@RestController
와@RequestMapping
을 사용해/api/dns
경로로 요청을 받는다.@GetMapping
메서드에서 사용자가 입력한domain
파라미터를 받아 처리한다.
@RestController
@RequestMapping("/api/dns")
public class DnsController {
private final DnsService dnsService;
public DnsController(DnsService dnsService) {
this.dnsService = dnsService;
}
@GetMapping("/cname")
public ResponseEntity<CnameResponse> getCname(@RequestParam(name = "domain") String domain) {
CnameResponse response = dnsService.getCnameRecord(domain);
return ResponseEntity.ok(response);
}
}
- DnsService.java
- 역할: DNSJava 라이브러리를 사용해 실제 CNAME 레코드를 조회한다.
Lookup
객체를 통해 DNS 서버와 통신하여 결과를 가져온다.- 성공적으로 조회된 경우
alias
와target
을 포함한 결과를 반환하고, 실패한 경우 적절한 메시지를 제공한다.
@Service
public class DnsService {
public CnameResponse getCnameRecord(String domain) {
try {
Lookup lookup = new Lookup(domain, Type.CNAME);
lookup.run();
if (lookup.getResult() == Lookup.SUCCESSFUL) {
for (Record record : lookup.getAnswers()) {
if (record instanceof CNAMERecord) {
CNAMERecord cnameRecord = (CNAMERecord) record;
return new CnameResponse(
cnameRecord.getName().toString(),
cnameRecord.getTarget().toString(),
"CNAME record found successfully"
);
}
}
}
return new CnameResponse(null, null, "CNAME record not found");
} catch (Exception e) {
return new CnameResponse(null, null, "Error: " + e.getMessage());
}
}
}
- CnameResponse.java
- 역할: API의 응답 데이터를 담는 DTO 이다.
- Lombok의
@Data
,@NoArgsConstructor
,@AllArgsConstructor
를 사용해 작성했다.
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CnameResponse {
private String alias;
private String target;
private String message;
}
배운 점
- DNS와 네트워크
통신 구조
를 이해할 수 있었다. DNS 서버가 CNAME 레코드를 반환하는 원리를 학습하며, 이를Java
코드로 구현하는 과정을 통해 네트워크 통신의흐름을 체계적
으로 익혔다. 단순히 기능을 구현하는 것을 넘어, DNS 서버와의요청 및 응답
과정을직접 설계
하면서 네트워크 통신의 동작 방식을 이해할 수 있었다. DNSJava 라이브러리
를 활용하여 DNS 서버와 통신하는 로직을 Spring Boot와 통합해 API 형태로 제공하는 과정을 통해, 외부 라이브러리를 연계하고 구현하는 방법을 익혔다. 이러한 경험은 향후 다른 외부 라이브러리나 API를 활용할 때에도 도움이 될 것이다.- 마지막으로 예상치 못한 상황,
도메인에 CNAME 레코드
가 없거나 네트워크 오류가 발생하는 경우를 처리하기 위해, 상세한 에러 메시지를 제공하고 로깅을 통해 문제의 원인을 추적할 수 있도록 구현했다. 이 프로젝트는 DNS와 네트워크, API 설계의 기초를 다지는 데 도움이 되었으며, 앞으로 더욱 복잡한 시스템을 설계할 때 밑바탕이 될 중요한 경험을 제공해 주었다.
향후 개선 및 확장 방향
다양한 DNS 레코드 조회 기능 추가
현재 프로젝트는 CNAME 레코드 조회 기능에 초점을 맞추고 있다. 그러나 DNS 레코드는 CNAME 외에도 다양한 유형이 있다.
A 레코드:
도메인의 IP 주소를 반환하는 레코드.MX 레코드:
이메일 서버 정보를 제공하는 메일 익스체인저 레코드.TXT 레코드:
도메인에 대한 텍스트 정보를 포함하는 레코드.
이러한 레코드들은 각각 고유의 용도와 중요성을 가지고 있어 네트워크 관리 및 시스템 설계에서 자주 사용된다. 이를 위해 Type.A
, Type.MX
, Type.TXT
와 같은 추가 타입을 지원하도록 프로젝트를 확장하고, 특정 DNS 레코드를 조회하는 기능을 제공할 계획이다.
응답 데이터 포맷 향상
{
"alias": "www.google.com.",
"target": "google.com.",
"message": "CNAME record found successfully"
}
응답 데이터는 간단하지만, 이를 더 구조화하기 위해 JSON
스키마를 활용할 계획이다.
- 구조화된 JSON 응답
CNAME 외에 다른 레코드 조회를 추가할 경우, 데이터의 구조가 복잡해질 수 있다. 이를 대비해 JSON 스키마를 정의하여 응답 데이터를 표준화할 수 있다.
- 메타데이터 추가
응답에 조회된 도메인의 추가 정보를 포함하도록 확장할 계획이다.
{
"alias": "www.google.com.",
"target": "google.com.",
"queryTime": "2024-12-17T10:00:00Z",
"server": "8.8.8.8",
"status": "SUCCESS",
"message": "CNAME record found successfully"
}
- 다국어 지원 메시지
메시지를 다국어로 제공하여, 다양한 언어를 사용하는 사용자들에게 친숙한 응답을 반환할 계획입니다.
결론
단순히 DNS 조회 기능을 구현하는 것을 넘어, Java와 Spring Boot를 활용해 실제 네트워크 환경에서 동작하는 기능을 개발하는 좋은 경험이 되었다. 이를 통해 DNS와 네트워크 통신의 기본 원리를 학습하고, CNAME 레코드와 같은 DNS 데이터가 실제로 어떻게 조회되고 처리되는지 깊이 이해할 수 있었다.
결론적으로, 이번 프로젝트는 네트워크 통신을 이해하고, 문제를 분석하고 해결하는 개발자로서의 역량을 키우는 계기가 되었다. 앞으로 이러한 경험을 바탕으로 프로젝트를 더욱 발전시키고, 가치를 제공하는 네트워크 도구로 완성시킬 계획이다.