네트워크 스터디 2주차 - DNS 서버

Jiwon An·2021년 9월 24일
1

CS/네트워크

목록 보기
7/10
post-custom-banner

1. DNS 등장 배경

인터넷 표준 프로토콜은 TCP/IP 이다.
TCP/IP 프로토콜을 사용하는 네트워크 안에서는 Host 들을 식별하기 위한 목적으로 IP 주소를 사용한다.
사람의 경우 이 IP주소를 일일히 기억하고 구분하기 힘들고, 숫자보다 문자를 사용하는 것이 더 편하기 때문에 도메인 이름을 사용하여 Host들을 식별한다.
도메인 이름을 사용하는 경우에도 최종적으로 IP주소를 알고 있어야 상대방 장비와 연결이 가능하다.
네트워크에서 도메인이나 호스트 이름을 IP 주소로 해석해 주는 TCP/IP Network Service인 DNS가 등장하였다.
도메인 이름을 IP주소로 변경하는 과정을 DNS Resolution이라고 하기에, 이러한 기능을 하는 서버를 DNS Resolver라고 부른다.

DNS 포트 번호
UDP와 TCP 포트 53번을 사용한다.

UDP : 일반적인 DNS 조회를 할 경우 사용한다.
TCP : Zone Transfer(영역 전송)와 512Byte를 초과하는 DNS 패킷을 전송해야 할 경우 사용한다.

2. DNS 과거와 현재

2.1 과거

예전에는 컴퓨터마다 hosts.txt 파일을 가지고 있었다.
파일 위치: C:\Windows\System32\drivers\etc\hosts

예시) hosts.txt

hosts 파일에는 모든 컴퓨터의 Hostname과 IP 주소 정보가 저장되어 있다.
클라이언트는 FTP를 이용해 접근해서 hosts 파일을 다운로드 및 적용하였다.
90년대 초반 웹 서비스 사용자가 폭발적으로 증가하면서 인터넷에 연결된 Host 숫자가 크게 늘어 났다.
그래서 호스트의 수정 및 업데이트가 늦어지고 네트워크 트래픽이 증가했고, 또한 호스트 이름을 짓기가 어려워졌다.(이름 중복)

2.2 현재

분산된 데이터베이스를 이용한다.
도메인이 워낙 많기 때문에 전 세계 모든 조직의 도메인정보를 갖고 있는 DNS 서버는 존재하지 않는다.
각 조직은 자신들의 도메인 정보를 관리하는 DNS 서버를 자체적으로 운영하고, 이러한 수 많은 도메인의 DNS 서버들이 상호 연동되어 있는 Domain Name Space를 구성하게 된다.

3. DNS의 구성 요소

3.1 도메인 네임 스페이스 (Domain Name Space)

DNS가 저장, 관리하는 계층적 구조를 의미한다.

최상위에 루트 DNS 서버가 존재하고, 그 하위로 인터넷에 연결된 모든 노드(네모 표시)가 연속해서 이어진 계층 구조로 구성되어 있다.
PC에서 사용하는 디렉토리 구조와 유사함을 알 수 있는데, 각 레벨(Top level, Second level 등)의 도메인은 그 하위 도메인에 관한 정보를 관리하는 구조이다. (계층적 구조)

  • 도메인(Domain)이란?
    도메인은 도메인 네임 스페이스의 서브트리이다. 도메인 이름은 서브트리의 맨 상위에 있는 노드에 위치한다.
  • Local DNS의 경우 일반적으로 DHCP 서버로부터 IP주소를 할당받았을 때 DNS 주소도 함께 받는다.

3.2 네임 서버 (Name Server)

문자열로 표현된 도메인 이름을 실제 컴퓨터가 통신할 때 사용하는 숫자로 표현된 IP 주소로 변환시켜 주기 위해서는 도메인 네임 스페이스의 트리 구조에 대한 정보가 필요하며, 이러한 정보를 가지고 있는 서버를 네임 서버라고 한다.
도메인 이름을 IP 주소로 변환하는 것을 네임 서비스라고 한다.
리졸버(Resolver)로 부터 요청 받은 도메인 이름에 대한 IP 정보를 다시 리졸버로 전달해주는 역할을 수행한다.

종류

1. 권한 서버 : 자신이 서비스할 영역을 가지고 IP Resolution을 해주는 서버

  • Primary Name Server
    • 해당 도메인을 관리하는 주 네임 서버이다.
    • Zone에 대한 모든 데이터를 가지고 있기 때문에 한 Zone에 대해서 모든 권한을 가지고 있는 서버
    • 파일로 저장된 Zone 정보를 메모리에 로딩하고 리졸버(클라이언트)에게 서비스를 해준다.
  • Secondary Name Server
    • primary 네임 서버의 고장 등의 이유로 동작하지 못하는 경우 이를 대신하여 네임 서버 역할을 수행하는 서버이다.
    • 주기적으로 Primary 네임 서버로부터 정보를 받아와 자신의 정보를 갱신하여 전체 네임 서버의 정보가 일관성 있게 유지 및 관리된다.

2. 캐싱 네임 서버

  • 자신이 서비스할 Zone이 없이 단지 외부에 있는 컴퓨터의 IP주소를 알아내서 리졸버(클라이언트)에게 서비스하는 네임서버
  • PC에서 해당하는 URL의 IP주소를 알려주는 네임서버이다.
  • 로컬 네임 서버에서 캐시DB의 역할을 하는 서버이다.

3. DNS의 종류(다른기준) authoritative DNS & 캐시 DNS

authoritative DNS 서버는 관리하고 있는 도메인의 IP주소를 갖고 있는 DNS 서버이다. 맨아래 계층에 있는 서버로, 특정 도메인에 대한 DNS 레코드를 추가/변경/삭제가 가능한 서버이다.
캐시 DNS(또는 recursive DNS)는 사용자로부터 DNS 정보조회 요청을 받을 때 authoritative DNS에서 정보를 가져와서 사용자에게 제공한다.

캐시 DNS는 사용자가 특정 도메인에 대한 DNS레코드를 요청할 때마다 authoritative DNS로 부터 정보를 가져오는 대신 한번 가져온 정보를 일정시간 동안 보관하게 되는데 그 시간을 TTL(Time To Live)라고 한다.

3.3 리졸버(Resolver)

웹 브라우저와 같은 DNS 클라이언트의 요청을 네임 서버로 전달하고 네임 서버로부터 정보(도메인 이름과 IP주소)를 받아 클라이언트에게 제공하는 기능을 수행한다.
하나의 네임 서버에게 DNS 요청을 전달하고 해당 서버에 정보가 없으면 다른 네임 서버에게 요청을 보내 정보를 받아 온다.
수많은 네임 서버에 접근하여 사용자로부터 요청 받은 도메인의 IP 정보를 조회하는 기능을 수행할 수 있어야 한다.

3.4 스터브 리졸버(Stub Resolver)

리졸버의 모든 기능을 PC와 같은 클라이언트 호스트에 구현하는 것은 단말 시스템 자원의 한계와 같은 제약이 있다.
리졸버의 대부분의 기능을 DNS 서버에 구현하고, 클라이언트 호스트에는 리졸버의 단순한 기능만을 지닌 리졸버 루틴을 구현한 것이다.
스터브 리졸버는 수 많은 네임 서버의 구조를 파악할 필요 없이 리졸버가 구현된 네임 서버의 IP 주소만 파악하면 된다.
도메인에 대한 질의를 받은 스터브 리졸버는 설정된 네임 서버로 DNS 질의를 전달하고 네임 서버로부터 최종 결과를 응답 받아 웹 브라우저로 전달하는 인터페이스 기능만을 수행한다.

4. DNS 동작 과정

1~3 : Root DNS 서버는 전체 FQDN 정보는 알지 못하기 때문에 자신의 하위 Domain인 com DNS 서버의 주소를 알려준다.

4~5 : 이를 수신한 Local DNS 서버는 다시 Iterative Query를 사용하여 com DNS 서버에게 정보를 요청하고, com DNS 서버도 자신의 하위 레벨 Domain인 naver.com의 DNS 서버 주소를 알려준다.

6~7 : 이를 수신한 Local DNS 서버는 다시 Iterative Query를 사용하여 naver.com DNS 서버에게 www 호스트에 대한 정보를 요청하고, naver.com DNS 서버는 www.naver.com에 대한 IP서버 주소를 알려준다.

8 : Local DNS 서버는 위와 같이 www.naver.com에 대한 IP주소를 수신 후 자신의 DNS Cache에 등록하고 해당 정보를 요청했던 클라이언트에게 응답메시지로 답변한다.

해당 클라이언트는 수신한 www.naver.com의 IP주소를 사용하여 실제 해당 서버에 패킷을 전송하게 된다. 그 후 Local DNS 서버는 다른 클라이언트에게 동일한 FQDN에 대한 DNS Query를 수신할 경우 DNS서버 Cache에 등록된 정보로 답변하는 것이 가능하다.

5. FQDN (Full Qualified Domain Name : 정규화된 도메인 이름)

네트워크 상에서 컴퓨터 시스템을 지칭하는 하나의 완전한 이름이다.
DNS의 서버이름은 hostname + domain name으로 표현된다.

Host name : 실제 서버에 주어진 컴퓨터의 이름이다. (www.naver)
Domain name : 논리적인 그룹을 표기한다. (.com)

6. Zone, Zone 파일

Zone이란 하나의 DNS가 관리하는 영역이다.
Zone은 그 Zone을 담당하는 DNS 서버와 그 Zone에 대해서 관리하는 데이터를 칭하는 Zone 파일로 구성된다.

Domain을 소유한 특정 조직의 DNS 서버는 해당 Domain에 대한 Zone 파일(영역 파일)을 갖는다.
해당 Zone 파일에는 해당 Zone이 담당하는 모든 자원 레코드(Resource Record)가 포함되어 있다.
이 파일엔 Domain 내부 정보(해당 Zone에 속한 호스트 또는 서브도메인 정보)가 존재하고, 해당 정보 조회를 허용하여 외부 클라이언트에게 정보를 제공할 수 있다.

6.1 Resource Record 종류

  • SOA : 해당 Domain 관리 권한 및 Zone Transfer(영역 전송)과 관련된 정보가 들어있다.
  • NS : NameServer의 정보를 갖고 있다.
  • A(AAAA) : 특정 host의 FQDN과 연결된 IP주소 정보를 갖는다.
  • CNAME : 특정 A레코드에 대한 별칭을 지정한다.
  • MX : Mail eXchange의 약자로 Mail 서비스에 관련된 정보를 갖고 있다. (해당 Domain의 Mail서버 정보)
  • PTR : 역방향 조회에 사용되는 레코드, 특정 IP주소에 대한 FQDN 정보를 가지고 있다.
  • ANY : 도메인에 대한 모든 레코드 질의 시에 주로 이용된다. (DNS 증폭 DDOS 공격에 악용)
  • 영역 전송(Zone Transfer)이란?
    마스터에 있는 원본 영역 데이터를 슬레이브가 동기화하는 작업을 의미한다.

6.2 DNS 조회

  • 정방향 조회 : Domain Name을 사용하여 IP주소를 조회한다.
  • 역방향 조회 : IP주소를 이용하여 Domain Name을 조회한다.

6.3 DNS 조회 절차

6.3.1 우선순위

1. 캐싱

서버가 다른 서버에게 매핑 정보를 요청하고 응답을 수신하면 이 정보를 클라이언트에게 전달하기 위해 캐시 메모리에 저장한다.
주소 해석 속도를 높일 수 있지만 오랫동안 캐싱 정보를 가지고 있다면 클라이언트에게 잘못된 매핑 정보를 제공할 수 있다.
네거티브 캐싱을 지원한다.

  • 네거티브 캐싱이란?
    잘못된 도메인에 관한 요청을 캐싱하여 불필요한 트래픽과 지연을 줄인다.

2. /etc/hosts

도메인/호스트명과 IP주소 매핑정보를 담고있는 파일로 질의하기 이전에 먼저 참조되는 파일이다.
파밍 공격을 하기 위해서 해당 파일을 변조하는 사례가 많으므로 관리가 필요하다.

  • 파밍 공격이란?
    사용자의 컴퓨터를 악성코드에 감염시켜 정상 홈페이지에 접속하여도 피싱 사이트로 유도되는 좀 더 고도화된 피싱이다.

6.3.2 클라이언트 PC에서 DNS 조회

사용자가 Domain Name을 사용하여 특정 Host와 통신을 원하는 경우 Client PC는 hosts파일을 먼저 보고 DNS Cache(ipconfig / displaydns)에 해당 도메인 정보가 있는지 확인한다.
만약 Hosts 파일 혹은 DNS Cache에 해당 정보가 존재하는 경우 해당 정보를 사용하여 패킷을 전송한다.
패킷이 존재하지 않는 경우에는 자신이 알고 있는 Local DNS 서버에서 DNS Query 메시지를 전송한다.

6.3.3 Recursive Query를 수신한 Local DNS 조회

해당 DNS Query를 수신한 서버는 자신의 Zone 파일(영역 파일)정보인지 확인한다.
자신의 Zone 파일 정보가 맞는 경우에는 A레코드에 등록된 IP주소로 응답한다.
자신의 Zone 파일 정보가 아닌 경우 DNS서버의 Cache 정보를 확인한다.
만약 Cache에 해당 정보가 등록되어 있는 경우 IP주소를 클라이언트에게 응답한다.
DNS 서버 Cache에 해당 정보가 없는 경우 Root hints를 참고하여 Root DNS 서버에게 Iterative Query를 전송하게 된다.

*Root hint?
DNS 서버가 모르는 도메인 네임을 받으면 루트 힌트에 있는 루트 도메인 서버 리스트를 보고 해당 루트 도메인 서버에게 질의를 통해 도메인 네임을 알아낸다.

zone “.”{
   type hint;
   file “named.root”; // 위와 같이 설정하고 named.root 파일을 생성해야한다.
}

6.3.4 간략 정리

  1. 클라이언트가 URL을 입력한다.
  2. /etc/host.conf 파일 조회 후 우선순위를 확인한다.
  3. /etc/hosts 파일을 열어 nate.com의 IP주소를 확인한다.
  4. hosts 파일에 IP 정보가 있다면 IP주소 획득 후 접속한다.
  5. hosts 파일에 없으면 /etc/resolv.conf 파일을 확인해 nameserver 네임서버IP 부분이 있는 지 확인한다.
  6. nameserver 네임서버IP에 IP 부분이 없다면 IP 주소 획득에 실패한다.
  7. nameserver 네임서버IP에 IP 부분이 적혀있다면 해당 네임서버에서 nate.com의 IP주소를 질의한다.
  8. 네임서버가 nate.com의 IP주소를 확인 후 알려준다.
  9. 네임서버가 응답하지 않으면 IP주소를 알 수 없다.

로컬 네임 서버란?

  • /etc/resolv.conf 에 저장된 네임 서버를 로컬 네임 서버라고 한다.
  • 내 PC가 접속하려는 호스트의 IP주소를 질의하는 서버이다.
  • TLD일 수도 있고, 캐시네임서버일 수도 있다.

6.3.5 로컬 네임 서버가 작동하는 순서

  1. PC의 웹 브라우저 주소창에서 www.nate.com을 입력한다.
  2. PC가 /etc/resolv.conf를 열어서 nameserver 네임서버IP 부분을 찾아 로컬 네임 서버 IP를 알아낸다.
  3. 로컬 네임 서버에 www.nate.com의 IP주소를 물어본다.
  4. 로컬 네임 서버는 자신의 캐시DB를 검색하여 www.nate.com의 정보가 들어있는지 확인한다.
  • 만약 정보가 있다면 바로 응답하지만 대개는 정보가 없다.
  1. 로컬 네임 서버는 Root 네임서버에 www.nate.com의 주소를 물어본다.
  2. Root 네임서버도 www.nate.com의 주소를 모르므로, com 네임서버의 주소를 알려주면서 com 네임서버에 물어보라고 한다.
  3. com 네임서버에 www.nate.com의 주소를 물어본다.
  4. com 네임서버도 www.nate.com의 주소를 모르므로, nate.com을 관리하는 네임 서버의 주소를 알려주면서 nate.com 네임서버에 물어보라고 한다.
  5. nate.com 네임서버에 www.nate.com의 주소를 물어본다.
  6. nate.com 네임서버는 ???.nate.com 이라는 이름을 가진 컴퓨터의 목록은 모두 가지고 있다. 그러므로 www.nate.com의 IP주소도 알고 있기 때문에 IP주소를 알려준다.
  7. 로컬 네임서버는 www.nate.com의 IP주소를 요구한 PC에 IP주소를 알려준다.
  8. PC는 획득한 IP주소로 접속을 시도한다.

DHCP

Dynamic Host Configuration Protocol의 약자

DHCP란 호스트의 IP주소와 각종 TCP/IP 프로토콜의 기본 설정을 클라이언트에게 자동적으로 제공해주는 프로토콜을 말한다. DHCP에 대한 표준은 RFC문서에 정의되어 있으며, DHCP는 네트워크에 사용되는 IP주소를 DHCP서버가 중앙집중식으로 관리하는 클라이언트/서버 모델을 사용하게 된다. DHCP지원 클라이언트는 네트워크 부팅과정에서 DHCP서버에 IP주소를 요청하고 이를 얻을 수 있다.

네트워크 안에 있는 컴퓨터에 자동으로 네임 서버 주소, IP주소, 게이트웨이 주소를 할당해주는 것을 의미하고, 해당 클라이언트에게 일정 기간 임대를 해주는 동적 주소 할당 프로토콜이다.

1. 장단점

장점

  • PC의 수가 많거나 PC 자체 변동사항이 많은 경우 IP설정이 자동으로 되기 때문에 효율적으로 사용 가능하고, IP를 자동으로 할당해주기 때문에 IP충돌을 막을 수 있다.

단점

  • DHCP 서버에 의존되기 때문에 서버가 다운되면 IP할당이 제대로 이루어지지 않는다.

2. DHCP 구성

2.1 DHCP 서버

DHCP 서버는 네트워크 인터페이스를 위해서 IP주소를 가지고 있는 서버에서 실행되는 프로그램으로 일정한 범위의 IP주소를 다른 클라이언트에게 할당하여 자동으로 설정하게 해주는 역할을 한다. DHCP 서버는 클라이언트에게 할당된 IP주소를 변경없이 유지해줄 수 있다.
클라이언트에게 IP 할당 요청이 들어오면 IP를 부여해주고 할당 가능한 IP들을 관리해주게 된다.

2.2 DHCP 클라이언트

클라이언트들은 시스템이 시작하면 DHCP서버에 자신의 시스템을 위한 IP주소를 요청하고, DHCP 서버로부터 IP주소를 부여받으면 TCP/IP 설정은 초기화되고 다른 호스트와 TCP/IP를 사용해서 통신을 할 수 있게 된다.
즉, 서버에게 IP를 할당받으면 TCP/IP 통신을 할 수 있다.

3. DHCP 프로토콜의 원리

DHCP를 통한 IP 주소 할당은 “임대"라는 개념을 가지고 있는데 이는 DHCP 서버가 IP주소를 영구적으로 단말에 할당하는 것이 아니고 임대기간(IP Lease Time)을 명시하여 그 기간 동안만 단말이 IP주소를 사용하도록 하는 것이다. 단말은 임대기간 이후에도 계속 해당 IP 주소를 사용하고자 한다면 IP 주소 임대기간 연장(IP Address Renewal)을 DHCP 서버에 요청해야 하고 또한 단말은 임대 받은 IP 주소가 더 이상 필요치 않게 되면 IP 주소 반납 절차(IP Address Release)를 수행하게 된다.

4. DHCP 절차

단말(DHCP 클라이언트)이 DHCP서버로 부터 IP주소를 할당(임대) 받는 절차에 대해 알아보자.
IP 주소 할당(임대) 절차에 사용되는 DHCP 메시지는 아래 그림과 같이 4개의 메시지로 구성되어 있다.

1. DHCP Discover (메시지 방향 : 단말 -> DHCP 서버)

  • 브로드캐스트 메시지 (Destination MAC = FF:FF:FF:FF:FF:FF)

  • 의미 : 단말이 DHCP 서버를 찾기 위한 메시지다. 그래서 LAN상에(동일 subnet상에) 브로드캐스팅을 하여 “거기 혹시 DHCP 서버 있으면 내게 응답 해주세요"라고 단말이 외친다.

  • 주요 파라미터

    • Client MAC : 단말의 MAC주소

2. DHCP Offer (메시지 방향 : DHCP 서버 -> 단말)

  • 브로드캐스트 메시지 (Destination MAC = FF:FF:FF:FF:FF:FF) 이거나 유니캐스트일 수 있다. 이는 단말이 보낸 DHCP Discover 메시지 내의 Broadcast Flag 값에 따라 달라지는데, Flag=1이면 DHCP 서버는 DHCP Offer 메시지를 Broadcast로, Flag=0이면 Unicast로 보내게 된다.

  • 의미 : DHCP 서버가 “저 여기 있어요" 라고 응답하는 메시지다. 단순히 DHCP 서버의 존재만을 알리지 않고, 단말에 할당할 IP주소 정보를 포함한 다양한 “네트워크 정보"를 함께 실어서 단말에 전달한다.

  • 주요 파라미터

    • Client MAC : 단말의 MAC 주소
    • Your IP : 단말에 할당(임대)할 IP 주소
    • Subnet Mask (Option 1)
    • Router (Option 3) : 단말의 Default Gateway IP 주소
    • DNS (Option 6) : DNS 서버 IP 주소
    • IP Lease Time (Option 51) : 단말이 IP 주소(Your IP)를 사용(임대)할 수 있는 기간(시간)
    • DHCP Server Identifier (Option 54) : 본 메시지(DHCP Offer)를 보낸 DHCP 서버의 주소, 2개 이상의 DHCP 서버가 DHCP Offer를 보낼 수 있으므로 각 DHCP 서버는 자신의 IP 주소를 본 필드에 넣어서 단말아 보낸다.

3. DHCP Request (메시지 방향 : 단말 -> DHCP 서버)

  • 브로드캐스트 메시지 (Destination MAC = FF:FF:FF:FF:FF:FF)

  • 의미 : 단말은 DHCP 서버(들)의 존재를 알았고, DHCP 서버가 단말에 제공할 네트워크 정보(IP주소, subnet mask, default gateway 등)를 알았다. 이제 단말은 DHCP Request 메시지를 통해 하나의 DHCP 서버를 선택하고 해당 서버에게 “단말이 사용할 네트워크 정보"를 요청한다.

  • 주요 파라미터

    • Client MAC : 단말의 MAC주소
    • Requested IP Address (Option 50) : 난 이 IP주소를 사용하겠다. (DHCP Offer의 Your IP주소가 여기에 들어간다.)
    • DHCP Server Identifier (Option 54) : 2대 이상의 DHCP 서버가 DHCP Offer를 보낸 경우, 단말은 이 중에 마음에 드는 DHCP 서버 하나를 고르게 되고, 그 서버의 IP주소가 여기에 들어간다. 즉, DHCP Server Identifier에 명시된 DHCP 서버에게 “DHCP Request” 메시지를 보내어 단말 IP주소를 포함한 네트워크 정보를 얻는 것이다.

4. DHCP Ack (메시지 방향 : DHCP 서버 -> 단말)

  • 브로드캐스트 메시지 (Destination MAC = FF:FF:FF:FF:FF:FF) 이거나 유니캐스트일 수 있다. 이는 단말이 보낸 DHCP Request 메시지 내의 Broadcast Flag=1이면 DHCP 서버는 DHCP Ack 메시지를 Broadcast로, Flag=0이면 Unicast로 보내게 된다.

  • 의미 : DHCP 절차의 마지막 메시지로, DHCP 서버가 단말에게 “네트워크 정보"를 전달해주는 메시지다. 앞서 설명한 DHCP Offer의 “네트워크 정보"와 동일한 파라미터가 포함된다.

  • 주요 파라미터

    • Client MAC : 단말의 MAC 주소
    • Your IP : 단말에 할당(임대)할 IP 주소
    • Subnet Mask (Option 1)
    • Router (Option 3) : 단말의 Default Gateway IP 주소
    • DNS (Option 6) : DNS 서버 IP 주소
    • IP Lease Time (Option 51) : 단말이 IP 주소(Your IP)를 사용(임대)할 수 있는 기간(시간)
    • DHCP Server Identifier (Option 54) : 본 메시지(DHCP Offer)를 보낸 DHCP 서버의 주소

이렇게 DHCP Ack를 수신한 단말은 이제 IP 주소를 포함한 네트워크 정보를 획득(임대)하였고, 이제 인터넷 사용이 가능하게 된다.


참고
https://peemangit.tistory.com/52
https://library.gabia.com/contents/domain/4152/
https://oopsys.tistory.com/203
http://kn.co.kr/asp/data/Product/DNS_DNSSEC_KeyperPlus.pdf
https://jwprogramming.tistory.com/35

profile
아무것도 모르는 백엔드 3년차 개발자입니다 :)
post-custom-banner

0개의 댓글