본문 바로가기
  • 냥냥냥
OS

3. 온프레미스에서 FQDN 구축하기: 유동 IP 환경에서 DDNS + 도메인 네임 서비스 구성 실습

by 프로그래밍데 2025. 6. 11.

지난 글에서 한 일 

일단 홈 서버에 내 외부 LTE 접속 방화벽 설정까지 해줘서 접속 되는거 까지 진행했다. 

그런데, 이 가정용 공유기는 말이다 
공인 ip가 계속 바뀌는 유동 ip이다. 
거기다 사실 고정 ip라 한들 , 이 ip를 언제 외우고 다니면서 검색을 할 거냐는 것. 
그래서 이 ip에게 다소 귀엽고 기억에 잘 남는 이쁜 이름을 지어 연결해줄 예정이당. 

그걸 이제 DNS라고 한다. . ..

 

* 혹시나 공격의 대상이 될까봐 글에서 적는 도메인 주소의 정보는 모두 example로 대체한다. *

 

 

(=> 이상하다 티스토리에서 내 사진을 삭제한 건지 No Image가 뜬다 ?_? 다음에 원인을 찾아올게요)

 

1단계: 유동 IP 환경에서 FQDN 적용

1-1. 도메인 네임 시스템(DNS) 적용의 필요성

앞서 말했듯, 가정용 네트워크 환경의 공인 IP는 일반적으로 유동(Dynamic)이며, DHCP에 의해 일정 주기로 변경됩니다.

 

이런 이유로 접속 경로의 지속성을 확보하기 어려워집니다.

지금 목표가
: DNS 기반의 정적 도메인 접근성을 확보하여,
123.123.123.123 → www.example 로
접근 경로를 구성하는 것.

즉, Fully Qualified Domain Name (FQDN) 을 통해
공인 IP 변경에 무관하게 도메인 네임으로 서버 접근이 가능해야 합니답.

 

1-2. 기존 클라우드 기반의 구성 방식과 비교를 해보자면

 

AWS 기준:

  • Route 53 에서 도메인 구매
  • Elastic IP (Static) 확보
  • EC2 인스턴스 연결 → 도메인 맵핑

=> 늘 그렇듯, 이렇게 해왔잖아요 aws에서 
도메인 구매하고, 도메인에 고정 ip 연결하고, EC2에 연결 .

하지만 지금 저는 클라우드 외부 환경, 즉 온프레미스 홈서버에서 동일한 인프라 흐름을 구축해야 합니당.

 

 

1-3 대략적인 네트워크 흐름

- 브라우저에 www.example 입력  

DNS 리졸버가 “A 레코드=123.123.123.123” 받음

- TCP 3-way handshake ⇢ 공유기 공인 IP로 패킷 전송

(A Recode가 뭔지 모르시는 분들은 https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-DNS-%EB%A0%88%EC%BD%94%EB%93%9C-%EC%A2%85%EB%A5%98-%E2%98%85-%EC%95%8C%EA%B8%B0-%EC%89%BD%EA%B2%8C-%EC%A0%95%EB%A6%AC#a_%EB%A0%88%EC%BD%94%EB%93%9C )

=> 갓파님의 블로그를 보십쇼 

 

 

그럼 일단 도메인 구매하러 가죵 

 

2단계: 도메인 등록 및 Cloudflare 연동

2-1. 도메인 확보

도메인 준비  

- freenom(무료)

- gabia(유료) 중 선택

 

일단 저 같은 경우에는 이 서비스 자체를 계속 띄워놓을 목적이 아니라 학습 목적이기 때문에 

freenom을 선택했었었었었습니다.(과거형) 

홈 서버를 계속 올려놓을 건 아니니까여 ㅎㅎ (라고 생각을 했었는데)

 

https://inpa.tistory.com/entry/WEB-%F0%9F%8C%90-%EB%AC%B4%EB%A3%8C-%EB%8F%84%EB%A9%94%EC%9D%B8DNS-%EB%B0%9C%EA%B8%89%EB%B0%9B%EA%B8%B0-Freenom#freenom_%EB%8F%84%EB%A9%94%EC%9D%B8_%EB%B0%9C%EA%B8%89%ED%95%98%EA%B8%B0

 

🌐 무료 도메인(DNS) 발급받기 - Freenom

무료 도메인 사용하기 도메인 네임으로서 가장 유명하고 많이들 쓰이는 .com, .net은 1년에 13000원, .kr은 1년에 9000원 정도로 꽤나 저렴한 편에 속한다. 그렇지만 단순히 공부 및 테스트 용도로서 도

inpa.tistory.com

 

인파님 블로그 참고해서 등록했었었었었어요

 

근데 저는 부득이하게도 

이렇게 다 무료는 불가능해서

 

결국 가비아를 선택했습니다 하하 여기가 더 싸더라구요 

그리고 사실 freenom은 일정 사용량이 넘어가면 자동으로 유료로 돌려버리기도 하고 ( 야비해 )

가비아로 결정 

 

 

500원의 행복 모 그런거

 

2-2. Cloudflare를 통한 DNS 위임  (NS 변경)

아 일단 제가 굉장히 친애하는 개발자분께서

이거 하는데 Cloudflare까지 왜 필요하냐고 하셨거든여

 

안해도 됩니다.

왜냐면 가비아에서도 A recode까지 추가가 가능하기 때문에 

www.example -> 123.123.123.123으로 연결은 가능하기 때문입니다.

 

근데 제 공인 ip DHCP라서 바뀐다고 했잖아요

바뀌면 또 가비아 가서 ip 변경해줘야 해요. 

 

스크립트로 레코드를 갱신하고 싶어도, 가비아는 DNS 레코드를 바꾸는 공개 API를 제공하지 않습니다.

거기다 HTTPS 적용하려면 인증서 따로 받고,,

설정 직접 해야 하고,,

자동 갱신도 어려움,,,,,

 

그리고 cloudflare가 reverse Proxy 역할도 해줌. 

 

클라이언트 -> cloudflare ->내 서버 

=> 그렇다보니까, 내 서버의 진짜 ip는 외부에 안 보인다는 장점이 있다. 

....

 

 

그래 나는 Cloudflare 하련다 글고 무료자녀

  • 가비아 등 도메인 업체는 DNS 제어권한이 제한적이구요
  • Cloudflare는 Name Server(NS) 위임을 통해 DNS의 제어권을 완전히 가져올 수 있습니당.
  • 이후 A 레코드, CNAME, DDNS 스크립트 자동화, SSL, 방화벽 등을 모두 Cloudflare에서 처리 가능해요 ! 

 

그런 이유로, 일단 도메인 네임서버 부터 Cloudflare로 위임해주어야 한당. 

 

https://dash.cloudflare.com/ => 접속해서

상단의 add로 도메인 추가

 

=> 가비아에서 산 도메인 이름 등록을 해주면 네임서버를 추천해줍니당.

 

=> 이제 이 네임 서버를 가비아의 네임서버에 위임 해주면 돼요 !! 

  1. https://www.gabia.com 로그인
  2. 도메인 관리 → 내 도메인 목록
  3. 사용 중인 도메인 클릭
  4. 네임서버 관리 or 네임서버 변경 메뉴로 이동

변경해주십쇼 

구럼 이제 권한을 cloudflare가 가지게 된다구요

 

다시 cloudflare로 돌아와서 

 

2-3. A 레코드 기본 구성

  • @ 레코드: example
  • www 레코드: www.example

흠 Name을 www랑 @ 둘 다 해야 한다.  

  • @만 등록 → example 연결됨.
    하지만 www.example은 "사이트 없음" 오류 발생.
  • www만 등록 → 반대의 상황 발생.

대부분의 유저는 www를 습관적으로 쓰기 때문에, 두 개 다 등록하는 게 표준이니  둘 다 등록하세영

 

 

 

3단계: DDNS 자동화 구성 (Cloudflare API 기반)

3-1. 문제 정의: 유동 IP와 A 레코드의 비동기성

  • 공유기 재부팅 또는 ISP 재할당으로 인해 IP가 바뀔 수 있음
  • 이 경우 도메인과 실제 서버 간의 매핑이 끊기게 됨 

=> DDNS 방식으로 현재 IP를 감지 후 Cloudflare A레코드를 자동으로 갱신해주면 된다. 

 

3-2 DDNS 자동화 설정 (공인 IP 자동 업데이트)

 

흐름 정의 : 

[유동 IP 홈서버] 
    ↓ 현재 IP 가져오기
[Cloudflare API]
    ↓ 도메인 A레코드 갱신
[Cloudflare DNS] 
    → www.example로 정상 연결

 

 

Cloudflare는 DDNS 기능을 직접 제공하진 않지만,

API를 통해 A 레코드를 자동으로 업데이트할 수 있다.

 

그래서 나는 DDNS 업데이트 스크립트를

리눅스 서버에 직접 설치해서 5분마다 IP 변경 확인 & 자동 갱신 해주는 로직을 선택했다. 

 

 

3-3 Cloudflare API Token 발급

  1. Cloudflare 대시보드 → 우측 상단 My Profile
  2. 왼쪽 메뉴에서 API Tokens 선택
  3. Create Token 클릭

 

 

4. 템플릿 중 Edit zone DNS 클릭

5. Zone Resources: Include > example (도메인 이름)

6. Permissions: Zone > DNS > Edit

모자이크 한 곳에 도메인 이름 입력

7. 생성 → 토큰 복사해서 안전하게 저장하세영

 

이제는 제 우분투 서버에 패키지를 설치 해주어야 해용 

sudo apt update
sudo apt install curl jq -y

 

여기서 용어 하나하나 설명을 좀 하자면

apt란 :  Ubuntu에서 프로그램 설치할 때 사용하는 패키지 매니저
  • Google Play나 앱스토어 같은거
  • 명령어로는 apt install, apt remove, apt update 등 있음.
  • update : 패키지 업데이트, install : 패키지 설치 , remove :  패키지 제거 
curl이란?
  • 인터넷 주소(예: API 서버)로 요청을 보내서 내용을 가져오는 도구.
  • 예: curl https://google.com → 구글 HTML 받아옴
  • → Cloudflare에 DDNS 요청 보낼 때 API 요청 보내기 위해 필요
jq란?
  • JSON 데이터를 쉽게 읽고 처리하는 도구/
  • API에서 받은 응답은 대부분 JSON 형태인데, jq 없으면 보기 힘듦.
-y란?
  • 설치할 때 "정말 설치할까요? [Y/n]" 물어보는 걸 자동으로 "Yes" 해주는 옵션.

한 줄 요약:

sudo apt update sudo apt install curl jq -y

→ 최신 버전으로 업데이트하고, API 요청 및 JSON 처리를 위한 도구를 설치하는 것.

 

 

3-4. 스크립트 만들기

1. 아래처럼 cloudflare-ddns.sh 파일을 만들어줍니다 (우분투 서버에요)

nano ~/cloudflare-ddns.sh
nano ~/cloudflare-ddns.sh

 

#!/bin/bash

# 여기에 여러분의 정보 입력!
CF_API_TOKEN="여기"              # Cloudflare에서 만든 API 토큰
CF_ZONE_NAME="yourdomain.com"    # 님들 도메인
CF_RECORD_NAME="yourdomain.com"  # 님들 도메인 (서브도메인도 가능)
CF_EMAIL="dummy@example.com"     # 이메일은 안 써도 됨 (참고용)

# 현재 공인 IP 얻기
IP=$(curl -s http://ipv4.icanhazip.com)

# 현재 Cloudflare의 A 레코드 IP 가져오기
ZONE_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones?name=$CF_ZONE_NAME" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result[0].id')

RECORD_ID=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records?name=$CF_RECORD_NAME" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result[0].id')

CURRENT_IP=$(curl -s -X GET "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
  -H "Authorization: Bearer $CF_API_TOKEN" \
  -H "Content-Type: application/json" | jq -r '.result.content')

if [ "$IP" != "$CURRENT_IP" ]; then
  echo "IP 변경 감지됨. 업데이트 중..."
  curl -s -X PUT "https://api.cloudflare.com/client/v4/zones/$ZONE_ID/dns_records/$RECORD_ID" \
    -H "Authorization: Bearer $CF_API_TOKEN" \
    -H "Content-Type: application/json" \
    --data "{\"type\":\"A\",\"name\":\"$CF_RECORD_NAME\",\"content\":\"$IP\",\"ttl\":1,\"proxied\":false}"
  echo "업데이트 완료: $IP"
else
  echo "IP 변경 없음: $IP"
fi

저장하고 Ctrl + O → 엔터 → 나가기 Ctrl + X

 

3-5. 실행 권한 주기

chmod +x ~/cloudflare-ddns.sh

 

3-6. 자동으로 주기적으로 실행되게 설정 (cron을 통해 스케쥴러 사용)

crontab -e

맨 아래에 이 줄 추가 (10분마다 실행)

=> 잘 실행이 되면 아래와 같은 문구 화면이 뜰 거에요.

한 마디로 지금은 아직 cron에 등록된 작업이 없고, " 스크립트 수정할 때 쓸 편집기에 어떤 걸 쓸래?" 라고 묻는 중인거에여

crontab - e
=> no crontab for 여러분의 예정 이름 - using an empty one 

Select an editor.  To change later, run 'select-editor'.
...

참고로 crontab은 크론을 실행하는 테이블입니당. 각종 명령어를 가지고 있어요. 

 

그리고 다음의 문구들이 이어서 나올 텐데여 
 
1. /bin/nano 
2. /usr/bin/vim.basic
3. /usr/bin/vim.tiny
4. /bin/ed

Choose 1-4[1]:
 
 

=>  nano가 가장 쉽고 무난하기 때문에 1 했습니당 저는 

 

편집기로 진입하면 이런 빈 화면이 나옵니당.

# Edit this file to introduce tasks to be run by cron. 
# ...
 
여기 젤 아래에 다음을 추가해줍니당.
*/10 * * * * /home/ubuntu/cloudflare-ddns.sh >> /var/log/cloudflare-ddns.log 2>&1

=> 10분에 한 번씩 ip 바뀌는거 확인해서 매핑해준다는 뜻입니당. 

 

  • */10 * * * *: 10분마다
  • /home/.../update_ddns.sh: 너의 DDNS 업데이트 스크립트 경로
  • >> .../ddns.log: 결과를 로그 파일로 저장 (에러 포함)

 

nano에서는:

  • 저장: Ctrl + O → 엔터
  • 나가기: Ctrl + X

 

끝 그럼 이제 

접속이 되어야 하는데

안 된다 왜냐 

바로 바로 내가 nginx도 안해줬으면서 

example로 접속했기 때문이지. 

 

이런 일반 도메인은 자동으로 http의 경우 80 포트로 넘어가기 때문에, 

일단 도메인이 잘 연결됐는지 확인하려면

cloudflare의 프록시 설정을 꺼줘야 합니다. 

 

=> 이렇게용 

 

https://dash.cloudflare.com 여기 대시보드로 가십쇼 

가서 레코드 A의 프록시 설정을 DNS Only로 바꾸어서 

cloudflare를 거치지 않고 본인들 공인IP:커스텀포트로 넘어가도록 하세요 !! 

일단 도메인 연결 잘 되는지 확인 해야 하니까용

 

 

그러고 나서 

ping example

을 하시면 

이제 cloudflare의 ip가 아니라

본인 집의 221.뭐 어쩌구의 공인IP가 노출 돼야 합니당. 

 

저 ping 했을때 모자이크한 IP가 본인 공인IP셔야 한다구용 

그럼 이제 제가 제 핸드폰 ios LTE의 공인IP를

sudo ufw allow from <LTE 공인IP> to any port <내 커스텀 포트> 

로 해서 규칙 추가해주고 접속해볼게용 

 

흑흑 행복하당 .. 

 

지금은

example:커스텀포트번호

해서 접속 된 건데, 

 

이제 다음 글에는 이런 포트 번호 안 써도 

도메인만 딱 써서 접속할 수 있도록 하는 ngnix server + https 설정 하겠습니당 ㅎㅅㅎ 

최근댓글

최근글

skin by © 2024 ttuttak