톺아보기 · n8n

n8n으로 유동 아이피 다루기

홈서버의 터널링을 없애 반응속도를 개선하고 유동 IP 문제를 n8n 시스템을 통해 해결했습니다.

저는 지금 집에 있는 맥미니로 n8n을 포함한 여러 서비스를 운영하고 있습니다.
홈서버를 구축했을 당시에는 클라우드플레어의 터널링 기능을 사용을 했었는데요,
KT 공유기의 공인 IP가 바뀌는 경우들이 좀 있어서 매번 신경을 쓰기가 귀찮았기 때문이에요.
(이 방식은 제가 스타트업에서 온프레미스를 설정을 했을 때 썼던 방식이기도 했고요.)

근데 제가 회사에서 사용했을 때는 크게 문제가 없었는데 홈서버에서 생긴 문제가 뭐였냐면
속도가 좀 많이 느렸어요. 외부에서 내부 에디터를 열어 가지고 편집을 할 때나
아니면 내부에서 도메인을 통해서 통신을 하는 그런 상황에서 항상 몇 초씩 걸리더라고요.

속도 병목 (2026년 9월 22일)

잰 것 결과
n8n.chaeminu.dev가 붙는 Cloudflare 거점 SJC (미국 산호세)
cloudflare.com이 붙는 거점 ICN (서울), 5ms
집 PC에서 도메인 IP로 ping 1.6~1.9초, 손실 25~50%
집 PC에서 n8n 요청 한 번 2~9초

이게 클라우드플레어 무료 플랜에서 흔한 일이기도 하다는데요, 무료 플랜을 사용했을 때 도메인이 한국인데 서울 거점으로 안 붙는 경우가 많다고 하더라고요.
유료 플랜으로 올리면 나아진다고는 하는데 월 25달러인 데다가 유료 플랜이라고 서울 거점으로 된다는 보장이 없다고 하더라고요.

실제 결과를 보시면 제 도메인이 미국 산호세에서 받고 있고 터널은 서울 쪽에 붙어 있으니까
집에서 요청을 보내면 미국을 갔다가 오니까 속도가 느릴 수밖에 없더라고요.

터널 제거

속도가 느린 것을 알아낸 지 3일 차인 9월 24일에는 내부 LAN 통신을 이용하면 개발은 빠르게 가능하다는 걸 알고, 굳이 수정하지는 않았습니다만, 이 포스팅을 작성하고 있는 9월 29일은, 내부 서버에 여러 서비스를 올리다 보니 서버 속도 때문에 터널을 제거하기로 마음먹었습니다.

  1. 공유기에서 TCP 80, 443 포트를 맥미니로 포워딩했습니다.
  2. 맥미니에 Caddy를 올렸습니다. 인증서 발급과 갱신은 Caddy가 알아서 해 줍니다.
  3. Cloudflare는 DNS로만 남겼습니다. 레코드를 전부 “DNS only” A 레코드로 바꿔서 집 공인 IP를 가리키게 했습니다.
집 PC에서 n8n 요청 한 번 값
터널 2~9초
직결 18~93ms

이제 예전과는 다르게 2~9초 걸리던 게 18~93ms가 됐습니다.
만족스러운 결과였습니다.

유동 IP

이제 결과랑은 별개로 유동 IP에 대한 설정을 해야 합니다.

일단 제일 쉬운 방법은 공유기에 내장된 DDNS를 설정하거나
스크립트를 작성해서 크론으로 돌리는 방법이 있었는데요
저는 최근에 구축하고 있는 n8n 시스템을 활용하는 방법을 선택했습니다.

먼저 공유기를 안 쓴 이유는 의존성을 줄일 수 있다고 생각했기 때문이에요.
공유기 DDNS에 CNAME을 걸면 도메인 조회가 클라우드플레어에서 공유기 회사의 DNS 서비스로 이어지는데요
확률이 낮긴 하지만 그쪽이 멈추면 제 사이트도 안 열립니다.
그리고 무엇보다 홈서버다 보니까 공유기가 바뀌는 경우가 있을 수 있어요.
그러면 그 주소도 다시 챙겨야 해서, 나중까지 생각해서 공유기는 선택하지 않았습니다.

“스크립트 20줄 정도 적고 크론으로 걸면 되지 않냐”고 할 수도 있는데요
사실 스크립트가 더 가볍고 고장 날 곳도 적은 게 맞아요.
그렇게 치면 n8n은 노코드 툴이라서 코드로 직접 작성하는 쪽이 더 강력하기도 하고요.

하지만 지금 돌아가고 있는 n8n 시스템이 있고
알림이나 로그 같은 것도 거기서 같이 활용하고 있기 때문에
n8n을 고르는 쪽이 그런 부분에서 조금 더 유리할 거라고 생각했어요.
n8n 자체가 지금 맥미니에서 돌아가고 있어서 새로 설치할 게 없었던 것도 이유고요.

토큰

Cloudflare API 토큰은 “Edit zone DNS” 템플릿으로 만들면 됩니다.

Cloudflare 토큰 설정

n8n에는 Header Auth 자격증명으로 넣었습니다.
Name은 Authorization, Value는 Bearer <토큰>입니다.

n8n 자격증명

워크플로

이제 n8n 시스템 내에서 공인 IP가 변경되었을 때, 이를 패치하도록 설정하면 됩니다.

n8n 워크플로

노드 하는 일
Every 5 Minutes 5분마다 실행
Get Public IP api.ipify.org에서 지금 공인 IP 조회
Get Cloudflare Zone 도메인 이름으로 존 ID 조회
List A Records 그 존의 A 레코드 전부 조회
Pick Records To Update 고칠 레코드만 선별
Update DNS Record 고른 레코드를 새 IP로 PATCH
Log IP Change 바뀐 내용을 표에 기록
Notify Server Alerts 디스코드 알림

여기서 핵심은 고칠 레코드를 고르는 부분입니다.

const ip = String($('Get Public IP').first().json.ip || '').trim();
if (!/^(\d{1,3}\.){3}\d{1,3}$/.test(ip)) { return []; }
const zoneId = $('Get Cloudflare Zone').first().json.result[0].id;
const records = $input.first().json.result || [];
const out = [];
for (const r of records) {
  if (r.type === 'A' && r.proxied === false && r.content !== ip) {
    out.push({ json: { zoneId, recordId: r.id, name: r.name, oldIp: r.content, newIp: ip } });
  }
}
return out;

코드는 짧은데 포인트가 세 가지 있습니다.

  • IP가 그대로면 빈 배열이 나가고 뒤에 있는 노드는 아예 돌지 않습니다.
  • 호스트를 추가해도 워크플로를 고칠 필요가 없습니다.
  • ipify가 이상한 값을 주면 아무것도 안 합니다.

알림

IP가 바뀌면 디스코드 서버-알림 채널로 메시지가 하나 옵니다.

🌐 집 공인 IP 변경
(옛 IP) → (새 IP)
갱신한 DNS 레코드: (갱신 레코드)
기록: n8n Data table ddns_log

n8n 시스템과 통합을 했기 때문에 쉽게 가능했습니다.

검증

Cloudflare 대시보드에서 lab 레코드를 일부러 1.2.3.4로 바꿔 놓고 기다려 봤습니다.

확인 결과
복구 다음 5분 주기인 13:40:24에 원래 IP로 돌아옴
ddns_log (도메인), 1.2.3.4 → 원래 IP, success
디스코드 메시지 1건 도착
(도메인) 200, 33ms

다음 5분 주기에 바로 원래 IP로 돌아왔고 기록과 알림도 정상적으로 들어왔습니다.

개선 사항

사실 완벽한 방법은 아니라고 생각합니다. 나중에 수정할 수 있다면 다음과 같은 내용을 우선적으로 수정하려고 합니다.

  • DDNS가 n8n에 얹혀 있습니다. IP가 바뀌는 순간에 n8n이 죽어 있으면 갱신이 안 되고, 그때는 대시보드에서 직접 고쳐야 합니다.
  • 길게는 5분 주기에 DNS 캐시 시간을 더한 만큼 사이트가 끊깁니다.
  • 공인 IP를 ipify 한 곳에만 물어봅니다.
  • IPv4만 봅니다. AAAA 레코드는 다루지 않습니다.
  • 집 IP가 DNS에 그대로 드러납니다.
  • 정전 등으로 회선이 끊기면 사이트도 같이 멈춥니다.

마치며

응답속도도 빨라지고, 바꾸고 나니 n8n 통합으로 여러 시스템에 활용할 수 있을 것 같아서 기대가 됩니다!