개발/개발 구현

[Spring Boot DDNS 자동 갱신] DuckDNS와 함께하는 DDNS IP 자동화 프로그램 만들기

jineddy 2025. 5. 1. 10:11
728x90

DDNS란? DuckDNS 설정? 공인 IP가 바뀌어도 외부 접속을 유지하는 방법!
이 글에서는 DuckDNS와 Spring Boot를 활용해 공인 IP 자동 갱신 프로그램을 만드는 방법을 소개합니다.

 

DDNS란? 왜 필요한가?

고정 IP가 없는 환경에서 외부 접속을 원할 때

DDNS(Dynamic DNS)는 공인 IP가 자주 변경되는 환경에서도 고정된 도메인 주소로 외부 접속이 가능하게 해주는 기술입니다.

예를 들어 집에서 웹서버, CCTV, NAS 등을 운영하는 경우, ISP(통신사)가 할당하는 IP는 일정 시간마다 변경될 수 있습니다. 이때 DDNS를 사용하면 example.duckdns.org 같은 고정 도메인 주소로 계속 접속할 수 있습니다.

무료 DDNS 서비스: DuckDNS

https://www.duckdns.org는 대표적인 무료 DDNS 서비스로, 간단한 토큰 인증으로 도메인 등록과 IP 갱신이 가능합니다.

 

DuckDNS IP 자동 갱신 문제

일반적으로 DuckDNS는 5분마다 IP를 갱신할 수 있도록 API를 제공하지만, 다음과 같은 상황에서는 수동 또는 주기적인 자동 갱신 프로그램이 필요합니다:

  • 공유기 자체에 DDNS 갱신 기능이 없음
  • ISP 변경으로 공유기 설정 초기화됨
  • 보다 정밀한 제어 및 로그 관리 필요

 

Spring Boot로 DuckDNS IP 자동 갱신하기

간단한 스케줄러 + WebClient 구조로 DuckDNS 갱신 API를 호출하는 Spring Boot 기반 프로그램을 구성해보겠습니다.

프로젝트 구성 개요

  • DdnsSvc.java : 공인 IP를 확인하고 DuckDNS 갱신 호출
  • DdnsScheduler.java : 매시 50분마다 자동 갱신 스케줄러 실행
  • application.yml 또는 DB : PUBLIC_IP_CHECK, DDNS_RE_NEW_URL 같은 설정 값 관리

DuckDNS 갱신 URL 구조

DuckDNS에서는 다음 형식으로 IP를 갱신할 수 있습니다.

https://www.duckdns.org/update?domains=yourdomain&token=your-token&ip=1.2.3.4

DdnsSvc.java – IP 확인 및 갱신 호출

@Slf4j
@RequiredArgsConstructor
@Service("ddnsSvc")
public class DdnsSvc {
	private final WebClient.Builder webClientBuilder;
	private final CommPropsSvc commPropsSvc;

	public Mono<String> renewDdns() {
		String publicIp = getPublicIp();
		if(StringUtils.isNotEmpty(publicIp)) {
			return callReNewDdns(publicIp);
		} else {
			return null;
		}
	}

	private String getPublicIp() {
		String result = null;
		try {
			Document doc = Jsoup.connect(commPropsSvc.get("PUBLIC_IP_CHECK")).get();
			Element ipElement = doc.getElementById("ip_address");
			if (ipElement != null) {
				result = ipElement.text().trim();
			}
		} catch (Exception e) {
			log.error("{}", e.getMessage(), e);
		}
		return result;
	}

	private Mono<String> callReNewDdns(String ip) {
		return webClientBuilder.build()
				.get()
				.uri(commPropsSvc.get("DDNS_RE_NEW_URL") + ip)
				.retrieve()
				.bodyToMono(String.class);
	}
}

 

  • getPublicIp()은 외부 페이지 HTML 파싱을 통해 공인 IP를 얻음
  • callReNewDdns()은 DuckDNS API 호출

DdnsScheduler.java – 스케줄러로 자동 실행

@Slf4j
@Component
@RequiredArgsConstructor
public class DdnsScheduler {
	private final DdnsSvc ddnsSvc;

	@Scheduled(cron = "0 50 * * * ?")
	public void reNewDdns() {
		Mono<String> result = ddnsSvc.renewDdns();
		if(result != null) {
			log.info("DDNS IP 갱신 : {}", result.block());
		} else {
			log.info("DDNS IP 갱신 : {}", result);
		}
	}
}

 

  • @Scheduled(cron = "0 50 * * * ?"): 매시간 50분마다 자동 실행
  • Mono.block()WebClient의 비동기 응답을 동기식으로 받아 로그 출력

설정값 예시

PUBLIC_IP_CHECK: https://ifconfig.me
DDNS_RE_NEW_URL: https://www.duckdns.org/update?domains=yourdomain&token=yourtoken&ip=

ifconfig.me란?

내 컴퓨터의 공인 IP 주소를 웹을 통해 간단히 확인할 수 있는 사이트

[https://ifconfig.me](https://ifconfig.me)는 외부에서 접속했을 때 현재 사용 중인 공인 IP(External IP) 를 텍스트 형식으로 알려주는 무료 웹서비스입니다.

주요 특징

 

  • IP 주소만 리턴 (필요한 정보만 깔끔하게 제공)
  • curl, wget 등 CLI 도구에서도 쉽게 호출 가능
  • HTML 형태로 호출하면 웹페이지를, plain text로 호출하면 IP만 응답
  • Spring, Python, Shell 등 대부분의 언어에서 쉽게 호출 가능

간단 테스트

  • 터미널에서
curl ifconfig.me

 

  • 웹 브라우저에서
https://ifconfig.me

접속하면 현재 사용하는 공인 IP 주소를 바로 확인할 수 있습니다.

HTML 사용 예 (Jsoup 파싱 시)

Document doc = Jsoup.connect("https://ifconfig.me").get();
Element ipElement = doc.getElementById("ip_address");
String publicIp = ipElement.text();

※ 위 코드에서 #ip_address는 페이지 구조가 바뀌면 작동하지 않을 수 있으니, text() 전체를 받아서 정제하는 방식도 고려해야 합니다.

주의 사항

  • 너무 자주 호출 시 차단될 수 있음 (DDOS 방지 목적)
  • 정기적인 호출 시 일정한 간격 유지 필요 (예: 1시간 간격)

대안 서비스

모두 비슷한 역할을 하며, 텍스트 형태로 IP를 응답합니다. 상황에 따라 대체하여 사용할 수 있습니다.

 

 

결론: 내 DDNS는 내가 지킨다!

이렇게 간단한 프로그램만으로도 DuckDNS 갱신을 자동화하고, 예기치 않은 IP 변경으로 외부 접속이 차단되는 상황을 방지할 수 있습니다.

중요: IP 확인 API나 DuckDNS 갱신 URL이 변경될 수 있으니, 정기적으로 확인 및 테스트가 필요합니다.

728x90