[네트워크] 우분투 서버 세팅에서의 네트워크

KH55S·2025년 12월 8일

인프라 환경 및 구성

  • 서버 하드웨어 : 노트북
  • 애플리케이션 : Docker container를 이용한 Django Web Server 등
  • 도메인 : 가비아에서 도메인 구매
  • 네임 서버 : 가비아 NS를 사용하지 않고 Cloudflare Name Server로 위임하여 관리
  • Cloudflare Tunnel (Zero Trust) 사용 : 포트 포워딩이나 DDNS 설정 없이, 아웃바운드 터널링을 통해 외부 접속 구현

외부 사용자 → 노트북 웹페이지 도달 경로

  • 이 통신 과정은 Cloudflare Tunnel 아키텍처를 기반으로 하며, 일반적인 클라이언트-서버 모델과 달리 Outbound-only connection을 활용한다.
  • 사용자가 브라우저 주소창에 내 도메인을 입력했을 때의 흐름
  1. DNS 조회 및 Edge 접속 (Client ↔ Cloudflare Edge)
    사용자는 DNS 조회를 통해 내 도메인의 IP 주소를 획득한다. 이때 반환되는 IP는 내 집의 IP가 아닌, 사용자와 가장 가까운 Cloudflare Anycast Edge Server의 IP이다.
    • Layer 3 (Network)
      • Source IP : 사용자 PC의 공인 IP
      • Destination IP : Cloudflare Anycast IP (ex. 104.21.x.x)
    • Layer 4 (Transport)
      • Protocol : TCP
      • Destination Port : 443 (HTTPS)
      • TCP 3-way Handshake가 사용자와 Cloudflare Edge 사이에서 성립된다.
    • Layer 5~7 (Session/Presentation/Application)
      • TLS Handshake : 사용자와 Cloudflare 간에 암호화 세션이 수립된다. Cloudflare가 인증서를 제시하고 세션 키를 교환한다.
      • HTTP Request : 사용자가 GET / 요청을 보낸다. 헤더의 Host: my-domain 필드를 통해 Cloudflare는 어떤 터널로 가야 할지 식별한다.

  2. Cloudflare 내부 라우팅 및 캡술화 (Cloudflare Edge ↔ Cloudflared Daemon)
    Cloudflare Edge 서버는 해당 요청을 복호화한 뒤, 연결된 Tunnel을 찾는다. 중요한 점은 Cloudflare Edge가 내 노트북으로 새로운 연결을 시도하는 것이 아니다. 노트북에 설치된 cloudflared 데몬이 사전에 Cloudflare Edge와 맺어놓은 장기 지속 연결(Long-lived persistent connection, 주로 HTTP/2 or QUIC over UDP)을 통해 데이터를 전송한다.
    • 동작 원리
      • 사용자의 HTTP 요청을 직렬화하여 캡슐화한다.
      • 이미 수립되어 있는 터널 세션을 통해 이 캡슐화된 데이터를 노트북의 cloudflared 데몬으로 Push 한다.

  3. 데몬의 요청 전달 (Cloudflared Daemon ↔ Local Django Container)
    노트북의 cloudflared 데몬은 터널을 통해 들어온 데이터를 수신하고 역캡슐화하여 원본 HTTP 요청을 복원한다. 그리고 로컬 네트워크(Docker Network) 내의 서비스로 새로운 HTTP 요청을 생성하여 보낸다.
    • Layer 3
      • Source IP : Docker Bridge Gateway IP (예: 172.17.0.1) 또는 데몬 컨테이너 IP
      • Destination IP : Django 컨테이너 IP (192.168.35.100에 매핑된 내부 IP)
    • Layer 4
      • Source Port: Random Ephemeral Port (임시 포트)
      • Destination Port: 8000 (Service URL 설정값)
    • Layer 7
      • cloudflared가 프록시 클라이언트가 되어 Django 서버(Gunicorn/Manage.py)에 GET / 요청을 전송한다.

포트 번호 생략이 가능한 이유 (Reverse Proxy & Port Translation)

  • Cloudflare 대시보드에서는 포트를 지정했지만, 브라우저에서 접속할 때는 포트를 명시하지 않아도 접속이 되는 이유는 무엇일까
  • => 리버스 프록시의 핵심 기능인 포트 변환 때문에 가능하다.
  1. 브라우저의 기본 동작 : 웹 브라우저는 URL 스키마 http:// 이면 80번, https:// 이면 443 포트를 기본값으로 사용하여 연결을 시도한다. 즉, 사용자가 도메인만 입력하면 브라우저는 자동으로 Destination Port: 443으로 패킷을 목적지(Cloudflare)로 보낸다.
  2. Cloudflare의 수신 : Cloudflare Edge 서버는 전 세계적으로 표준 웹 포트인 80과 443을 열어두고 대기한다. 사용자의 트래픽은 이 443 포트로 수신한다.
  3. 내부 매핑 : Cloudflare Tunnel 설정에 Service: http://192.168.35.100:8000이라고 명시했다.
    • 이 설정의 의미는 외부에서 들어오는 Ingress 트래픽을, 내부의 8000번 포트로 전달하라는 규칙이다.
  4. 결과
    • Client ↔ Cloudflare : 443 포트 통신 (표준 HTTPS)
    • Cloudflared ↔ Django : 8000 포트 통신 (내부 설정)
    • 두 세션은 물리적으로 분리되어 있으며, cloudflared 데몬이 중간에서 포트 번호를 변환하여 새로운 TCP 연결을 맺어주기 때문에 사용자는 8000번을 알 필요도, 입력할 필요도 없다.

네임서버의 역할과 변경 이유

  • 기존의 가비아 네임서버를 Cloudflare의 네임서버로 변경하였다. 그 이유는 무엇일까

  • 네임서버(Authoriative Name Server)란?
    • 특정 도메인 영역에 대한 최종 권한을 가진 DNS 서버.
    • 이 도메인의 IP 주소는 무엇인가?, 서브 도메인은 무엇이 있는가? 같은 질문에 대해 정답(DNS Record)을 줄 의무와 권한이 있는 서버이다.

  • Cloudflare 네임서버로 변경한 기술적 이유
    • 가비아 네임서버는 단순히 도메인 → 고정IP를 매핑해주는 정적 레코드 관리 기능 위주이다. 반면 Cloudflare를 사용한다는 것은 Cloudflare가 트래픽의 대리자(Proxy)가 된다는 뜻이다.
    1. 트래픽 인터셉트 : 사용자가 도메인을 조회했을 때, 실제 서버(내 노트북)의 IP가 아닌 Cloudflare의 Edge IP를 반환해야 한다. Cloudflare는 이 IP를 트래픽 상황, 디도스 공격 여부, 사용자 위치에 따라 동적으로 변경한다.
    2. DNS 레코드의 동적 관리 : Cloudflare Tunnel을 연결하면 터널이 활성화될 때마다 연결된 CNAME 레코드를 Cloudflare 네임서버가 즉시 인식하고 응답해야 한다. 가비아 네임서버에 있다면 Cloudflare가 이 레코드를 마음대로 제어할 권한이 없다.
    3. 권한 위임 : 따라서 도메인 관리 권한을 가비아에서 Cloudflare로 이관하여, Cloudflare가 DNS 조회 요청에 대해 자신의 Edge 서버로 오라고 직접 답변을 할 수 있게 만든 것이다.

  • 외부 사용자가 도메인 입력 시 Cloudflare NS가 하는 일
    1. 사용자 PC의 Local DNS가 최상위 도메인(.cloud, .com) 관리 서버(Registry)에 myserver.cloud의 네임서버가 어디인지 묻는다.
    2. Registry는 Cloudflare 네임서버로 가라고 응답한다.
    3. Local DNS가 Cloudflare 네임서버에 website.myserver.cloud의 IP는 뭐냐고 묻는다.
    4. Cloudflare 네임서버는 설정된 Proxied 상태를 확인하고, 실제 노트북 IP가 아닌 Cloudflare Anycast IP 목록을 반환한다.

    5. HTTPS 연결 수립 및 요청 도달 (Client → Cloudflare Edge)
      • 사용자 PC(브라우저)는 반환받은 Cloudflare Anycast IP(사용자와 가장 가까운 엣지 서버)의 443 포트로 TCP 연결을 시도한다. 이후 TLS Handshake를 통해 암호화된 세션을 수립하고, HTTP 요청(GET/POST 등)을 전송한다.
    6. 터널 세션을 통한 트래픽 전달 (Cloudflare Edge → Laptop)
      • 요청을 받은 Cloudflare 엣지 서버는 HTTP 헤더의 Host 필드(ex. website.myserver.cloud)를 확인하여 해당 도메인과 매핑된 Tunnel ID를 식별한다. 그 후, 내 노트북의 cloudflared 데몬이 미리 연결해 둔 지속적인 아웃바운드 세션(Persistent Connection)을 통해 사용자 요청 데이터를 캡슐화(Encapsulation)하여 노트북으로 전송(Push)한다.

  • 네임서버를 Cloudflare로 변경한 근본적인 이유는 Cloudflare가 트래픽의 중계자(Reverse Proxy) 역할을 수행하기 위해서 (프록시와 애니캐스트)
    • 권한 위임 (Authority Delegation) : 가비아의 네임서버는 단순히 도메인=IP 정보를 알려주는 전화번호부 역할만 한다. 반면, Cloudflare 네임서버를 쓴다는 것은 도메인에 대한 모든 제어권을 Cloudflare에게 넘기는 것이다.
    • IP 마스킹 (Proxying) : 사용자가 도메인을 조회할 때, Cloudflare 네임서버는 실제 서버 IP가 아닌 Cloudflare Edge 서버의 IP를 반환한다. 이를 통해 공격자로부터 실제 서버의 위치를 숨길 수 있다.
    • 애니캐스트 (Anycast) 라우팅 : 사용자가 받는 IP는 그때그때 변하는 것이라기보다, 전 세계에 흩어진 Cloudflare 서버들이 동일한 IP를 공유하는 방식이다. 서울 사용자는 서울의 Cloudflare 센터로, 뉴욕 사용자는 뉴욕 센터로 최단 경로로 접속하게 된다. 이러한 고도화된 라우팅 기술을 쓰기 위해 네임서버를 변경한 것이다.

📌 DNS 레코드와 CNAME의 역할
DNS 레코드란 네임서버가 가지고 있는 설정 데이터 한 줄을 의미한다. 이 도메인은 어떤 IP로 가라, 메일 서버는 어디다 같은 구체적인 지시사항이다.

그 중 CNAME(Canonical Name) 레코드별칭을 지정하는 레코드이다.

  • 기능 : 도메인의 이름을 IP 주소로 직접 연결하는 것이 아니라, 또 다른 도메인 이름으로 매핑한다.
  • Cloludflare Tunnel에서의 역할
    • 터널을 생성하면 Cloudflare는 내부적으로 고유한 주소를 생성한다.( ex. [UUID].cfargotunnel.com )
    • 대시보드에서 website.myserver.cloud를 등록했을 때, 실제 DNS 내부에서는 website.myserver.cloud가 [UUID].cfargotunnel.com을 가리키도록 CNAME 레코드가 생성된 것이다.
    • 즉, 이 도메인으로 들어오는 요청은 저 터널 주소로 토스하라는 이정표 역할을 한다.

네임서버 변경 반영 지연 (DNS Propagation & TTL)

  • 네임서버를 변경했을 때 즉시 반영되지 않는 현상은 인터넷상의 DNS 캐싱 구조TTL 때문이다.

  • 인터넷상에서 발생하고 있는 작업 (Propagation 과정)
    1. Registry 업데이트 : 가비아에서 네임서버 정보를 수정하면, 가비아는 상위 기관인 .cloud Registry에 이 도메인의 담당자가 Cloudflare NS로 바뀌었다고 신호를 보낸다. (비교적 빠름)
    2. 전 세계 ISP/Recursive DNS의 캐시 만료 대기
      • 전 세계의 KT, Google DNS 등의 재귀적 해석기(Recursive Resolver)들은 효율성을 위해 한 번 조회한 네임서버 정보를 저장해 둔다. (캐싱)
      • 이 정보에는 TTL이 설정되어 있다. (보통 24시간~48시간)
      • 예를 들어, KT DNS 서버가 1시간 전에 myserver.cloud의 네임서버가 가비아라고 조회했다면, TTL 만료될 때까지는 다시 조회하지 않고 메모리에 있는 가비아 정보를 사용자에게 준다.
    3. 결과
      • TTL이 만료된 지역/ISP의 사용자는 새로 업데이트된 Cloudflare 네임서버 정보를 받아 접속이 된다.
      • 아직 TTL이 남은 DNS 서버를 쓰는 사용자는 여전히 가비아 네임서버를 참조하려 하므로 접속이 안 되거나 예전 설정으로 연결된다.
      • 이 시간이 지나면서 전 세계 DNS 서버들의 캐시가 하나둘씩 갱신되는 과정을 DNS 전파(Propagation)라고 한다.

사설 IP인 노트북으로 연결되는 원리 (Outbound-only Connection)

  • Cloudflare Tunnel 기술의 NAT Traversal
  • 일반적으로 외부(Cloudflare)에서 내부(사설 IP 노트북)로 접속(Inbound)하려면 방화벽과 NAT가 막고 있기 때문에 포트 포워딩 없이는 불가능하다. Cloudflare Tunnel은 이 방향을 반대로 뒤집어서 해결한다.
  1. 아웃바운드 연결 시작 : Cloudflare 서버가 노트북을 찾는 것이 아니다. 노트북에 설치된 데몬이 먼저 Cludflare Edge Server로 연결을 시도한다.
  2. 방화벽 통과 : 대부분의 가정용 공유기와 방화벽은 외부에서 들어오는 연결은 차단하지만, 내부에서 외부로 나가는 연결(Outbound)은 허용한다. (웹서핑을 할 수 있는 원리)
  3. 지속적 세션 수립 : cloudflared는 Cloudflare 네트워크와 암호화된 장기 지속 세션을 맺는다. 한 번 연결되면 끊지 않고 계속 유지한다.
  4. 요청 전달 : 외부 사용자가 Cloudflare 서버에 접속하면, Cloudflare는 이미 열려 있는 세션을 통해 요청 데이터를 노트북으로 밀어 넣는다.
  5. 도달 : 결과적으로 Cloudflare는 노트북의 IP를 알 필요가 없다. 단지 노트북이 먼저 연결해 온 연결 통로를 통해 데이터를 주고 받는다.

    노트북의 IP를 알 필요가 없다의 기술적 의미
    Cloudflare가 내 노트북의 IP를 모른다는 말은 Layer 3의 엔드포인트 관점에서의 설명이다.

    1. Transport Layer (TCP/UDP) 관점
      • Cloudflare는 데이터를 보낼 때 목적지를 211.200.x.x:10001 (공유기 공인 IP)로 설정해서 보낸다.
      • 즉, Cloudflare는 공유기까지의 주소만 알고 있다. 공유기 뒤에 192.168.35.100이 있는지, 192.168.35.101이 있는지는 패킷 헤더에 없으므로 알지 못합니다.
    2. 데이터 반환 과정 (DNAT)
      • Cloudflare가 211.200.x.x:10001로 응답 패킷을 보내면, 공유기가 이를 받는다.
      • 공유기는 아까 작성해 둔 NAT 테이블을 조회한다.
      • 외부 포트 10001로 들어온 데이터는 내부의 192.168.35.100:54321로 보내라는 기록을 확인한다.
      • 공유기가 목적지 IP를 192.168.35.100으로 다시 변환(=DNAT)하여 노트북에 전달한다.

  • 그렇다면 세션이 최초로 연결될 때에는 공유기의 NAT를 통해 내 노트북(서버)의 사설 IP를 공인 IP로 변환해야 통신이 성립된다.
    • cloudflared 데몬이 Cloudflare Edge 서버에 연결을 맺자고 요청할 때(TCP SYN 패킷 전송), 패킷은 다음과 같이 변환된다. => SNAT
  1. 노트북에서 사설 IP를 출발지로 하여 패킷을 만든다.
    • Source IP : 192.168.35.100 (노트북 사설 IP)
    • Source Port : 54321 (임의의 포트)
    • Destination IP : 104.21.x.x (Cloudflare 공인 IP)
    • Destination Port : 7844 (Cloudflare Tunnel 포트)
  2. 공유기 (NAT 변환 및 기록)
    • 공유기는 이 패킷을 인터넷으로 보내기 전, 자신의 NAT 테이블(NAT Table)에 기록을 남기고 출발지 주소를 바꿔치기 한다.
    • NAT 테이블 기록 : 내부 192.168.35.100:54321에서 나가는 요청을, 외부용 포트 10001에 매핑한다.
    • 패킷 변환 (IP Header 수정)
      • Source IP: 192.168.35.100 → 211.200.x.x (통신사 할당 공인 IP)
      • Source Port: 54321 → 10001 (공유기가 할당한 외부 포트)
    • 이 변환된 패킷이 인터넷망으로 송출된다.
  3. Cloudflare 서버 (수신)
    • Cloudflare 서버는 이 패킷을 받는다. 이때 Cloudflare가 보는 출발지 IP는 노트북 IP가 아닌 공유기의 공인 IP(211.200.x.x)이다.
    • Cloudflare는 이 공인 IP와 맺어진 TCP 소켓(Socket)을 터널 세션으로 유지한다.

0개의 댓글