IP란?
컴퓨터는 IP주소라는 주소를 가지고 통신한다. IP 주소는 총 32비트로 이루어져 있으며 .
을 기준으로 8비트씩 분리된다.
💡 IP프로토콜을 사용하지 않고 MAC 주소만을 사용해 통신할 수도 있기는 함.
(8비트.8비트.8비트.8비트)
이렇다면 총 IPv4 체계에서 생성할 수 있는 주소의 개수는 $$2^{32}=4,294,967,296$$개, 즉 약 43억개이다. 전세계 인류가 80억명 정도이니, 인당 컴퓨터 하나씩만 한다고 해도 IPv4의 주소 범위를 뛰어넘는다. 이를 해결하기 위해 IPv6라는 새로운 표준이 제정되었지만, 아직 널리 사용되지는 못하고 있다.
CIDR 표기법
IP의 범위를 표기할 때에는 CIDR 표기법을 주로 사용한다. CIDR표기법은 시작 IP 주소를 표기하고 /
를 표기한 이후, 고정할 앞 n 개의 비트 개수를 표기해야 한다.
192.168.0.0/16 → 192.168.0.0 – 192.168.255.255
내부망(사설망)이란?
공인IP는 ICANN에서 관리하고, ISP가 개인에게 할당한다.
flowchart LR; subgraph ISP회원 회원1;회원2 end ICANN --1.1.0.0/16--> ISP --1.1.23.54--> 회원1 ISP --1.1.27.23--> 회원2
flowchart LR;
subgraph ISP회원
회원1;회원2
end
ICANN --1.1.0.0/16--> ISP --1.1.23.54--> 회원1
ISP --1.1.27.23--> 회원2
공인IP는 한정된 자원이기에 각 회원당 IP를 무한정 할당해 줄 수 없다. 하지만 한 회원당 컴퓨터를 하나만 사용하는 것은 아니니 공인IP를 여러 기기에서 동시에 사용할 수 있도록 해야 한다. 이를 가능하게 하는 것이 공유기(가정에서) 또는 라우터(기업에서)이다.
💡 가정용 무선공유기는 방화벽+라우터+허브+AP+DHCP서버 등등..을 합쳐 하나로 만든 기기이다.
라우터는 공인 IP를 받고, 내부망을 구축한다. 이때, 내부망에서는 공유기 임의로 내부에서만 사용할 수 있는 사설IP를 각 기기에 할당하는데, 이들 IP는 공인 IP와는 충돌하면 안 되기에, 내부망 IP로 사용할 수 있는 대역이 다음과 같이 정해져 있다.
- Class A
- 10.0.0.0/8 (16,777,216개)
- Class B
- 172.16.0.0/12 (1,048,576개)
- Class C
- 192.168.0.0/16 (65,536개)
이들 범위 내부는 공인 IP로 할당하지 않는 범위로, 누구나 자유롭게 사용할 수 있다. 일반적인 가정에서는 Class C 범위를 주로 사용한다.
flowchart TB; ISP --1.1.23.54--> 공유기 subgraph 회원1의 공유기 내부망 공유기 --192.168.0.2--> 컴퓨터1 공유기 --192.168.0.3--> 컴퓨터2 공유기 --192.168.0.4--> 셋톱박스 공유기 --192.168.0.5--> 휴대폰 end
flowchart TB;
ISP --1.1.23.54--> 공유기
subgraph 회원1의 공유기 내부망
공유기 --192.168.0.2--> 컴퓨터1
공유기 --192.168.0.3--> 컴퓨터2
공유기 --192.168.0.4--> 셋톱박스
공유기 --192.168.0.5--> 휴대폰
end
위와 같은 그림대로, 공유기가 회원1의 가정 내 각 기기에 사설IP를 할당하였다.
💡 IP를 자동적으로 할당하는 일은 공유기 내부의 DHCP서버가 한다. IP가 할당되면 ARP를 통해 기기 mac 주소와 IP 주소를 맵핑시킬 수 있다.
컴퓨터가 IP를 할당받는 방법
컴퓨터에는 NIC(네트워크 인터페이스 카드)가 내장되어 있습니다. 유선 NIC의 경우 RJ45 LAN 포트가 내장되어 있는 것이 대중적이며, 서버용 장비에는 SFP포트가 있어 사용환경에 맞게 여러 케이블을 사용할 수 있도록 한 것도 있습니다.
무선 NIC의 경우 Wifi를 통해 무선으로 랜에 연결할 수 있도록 합니다.
이러한 NIC와 라우터가 연결되면, 기본적으로 DHCP를 통해 자동으로 IP를 할당받으려 시도합니다.
- DHCP Discovery
NIC와 라우터가 연결되었을 때, 브로드캐스팅 IP 주소(255.255.255.255), 67번 포트로 UDP패킷을 전송합니다.💡 255.255.255.255는 브로드캐스팅 주소로, 이 주소로 패킷을 전송하면 라우터는 랜에 존재하는 모든 컴퓨터에게 이 패킷을 전달하게 됩니다.
💡 이때 랜에 연결하고자 하는 호스트는 자신의 주소가 없기 때문에, 출발지 주소는 0.0.0.0 입니다.
flowchart subgraph 회원1의 라우터 내부망 direction TB 라우터 --192.168.0.2--o DHCP서버 라우터 --?.?.?.?--o 컴퓨터1 컴퓨터1 -- 255.255.255.255 : DHCP Discovery --> 라우터 라우터 -.DHCP Discovery.-> DHCP서버 end
flowchart subgraph 회원1의 라우터 내부망 direction TB 라우터 --192.168.0.2--o DHCP서버 라우터 --?.?.?.?--o 컴퓨터1 컴퓨터1 -- 255.255.255.255 : DHCP Discovery --> 라우터 라우터 -.DHCP Discovery.-> DHCP서버 end
classDiagram note "DHCP Discover\nAsrc:0.0.0.0:68\ndest:255.255.255.255:68\nyiaddr:0.0.0.0\ntransaction ID: 14"
- DHCP Offer
해당 랜에 DHCP서버가 존재한다면, DHCP Server Discovery 메시지를 받은 후, 다시 브로드캐스팅을 통해 DHCP Server Offer 메시지를 전송합니다. 이때, Offer 에는 다음 정보들을 포함합니다.flowchart subgraph 회원1의 라우터 내부망 direction TB 라우터 --192.168.0.2--o DHCP서버 라우터 --?.?.?.?--o 컴퓨터1 라우터 --DHCP Offer --> 컴퓨터1 DHCP서버 -- 255.255.255.255 : DHCP Offer --> 라우터 end
flowchart subgraph 회원1의 라우터 내부망 direction TB 라우터 --192.168.0.2--o DHCP서버 라우터 --?.?.?.?--o 컴퓨터1 라우터 --DHCP Offer --> 컴퓨터1 DHCP서버 -- 255.255.255.255 : DHCP Offer --> 라우터 end
classDiagram note "DHCP Offer\nAsrc:192.168.0.2:68\ndest:255.255.255.255:68\nyiaddr:192.168.0.3\ntransaction ID: 14\nDHCP server ID: 192.168.0.2\nLifetime: 3600 secs"
- 수신된 메시지의 트랜젝션 ID
- 할당한 IP 주소
- 서브넷 마스크
- IP 주소 임대 기간
- DHCP Request
랜 내부에는 DHCP서버가 여러개 있을 수 있으므로, DHCP Offer 중 하나를 선택해 DHCP Ack 메시지를 만들어 응답한다. - DHCP Ack
사설망(내부망)과 외부와 통신하는 방법
사설망과 외부망이 통신하는 방법에는 크게 NAT테이블을 사용하는 방법과, 포트포워딩 테이블을 사용하는 방법이 있다. NAT 테이블은 아웃바운드 통신에서 사용할 수 있고, 포트포워딩 테이블은 인바운드 통신에서 사용할 수 있다.
flowchart subgraph 기업의 내부망 165.232.123.5 direction TB 라우터1[라우터] --10.0.0.2--o 서버1 라우터1[라우터] --10.0.0.3--o 서버2 라우터1[라우터] --10.0.0.4--o 서버3 라우터1[라우터] --10.0.0.5--o 서버4 end subgraph 회원1의 라우터 내부망 152.242.291.281 direction TB 공유기 --192.168.0.3--o 컴퓨터1 end
flowchart
subgraph 기업의 내부망 165.232.123.5
direction TB
라우터1[라우터] --10.0.0.2--o 서버1
라우터1[라우터] --10.0.0.3--o 서버2
라우터1[라우터] --10.0.0.4--o 서버3
라우터1[라우터] --10.0.0.5--o 서버4
end
subgraph 회원1의 라우터 내부망 152.242.291.281
direction TB
공유기 --192.168.0.3--o 컴퓨터1
end
위와 같은 상황에서 컴퓨터 1이 특정 기업의 홈페이지에 접근하려 한다. 이때 회원1의 내부망에서는 NAT테이블로 아웃바운드 요청을 보내고, 기업의 내부망에서는 포트포워딩 테이블을 통해 인바운드 요청을 받는다.
먼저, 컴퓨터 1이 기업의 공인 IP인 165.232.123.5
로 http 요청을 보낸다. 이 때, 공유기(가정에서의)가 NAT테이블에 사용 가능한 포트 하나를 확보하게 된다.
공유기의 NAT테이블
공인 IP | 공인 Port | 사설 IP | 사설 Port |
152.242.291.281 | 1234 | 192.168.0.3 | 80 |
그 이후, 해당 패킷은 공유기가 다시 목적지를 향해 전송한다. 이때, 발송주소가 공유기의 공인 IP와 공유기가 할당한 공인 Port로 바뀌어 공인망을 통해 전달된다.
💡 목적지 주소는 바뀌지 않는다. 즉 165.232.123.5:80 으로 계속 전달된다.
공인망을 타고 기업의 라우터에 패킷이 도착하면, 이를 연결된 각 서버에 전달하여 처리해야 한다. 이때 이를 정의해 놓은 곳이 포트포워딩 테이블이다. 이 테이블은 NAT테이블과 다르게 사전 정의하지 않으면 (목적지 포트가 정의되어 있지 않으면) 패킷은 버려진다.
기업측 라우터의 포트포워딩 테이블
공인 IP | 공인 Port | 사설 IP | 사설 Port |
165.232.123.5 | 80 | 10.0.0.2 | 80 |
위와 같이 설정되어 있을 때, 공인 IP에 80번 포트로 요청이 전송되면 10.0.0.2:80 으로 전달하겠다는 뜻이다.
flowchart subgraph 공인망 direction TB subgraph "기업의 내부망 165.232.123.5" direction TB 라우터1[라우터] --10.0.0.2--o 서버1 라우터1[라우터] --10.0.0.3--o 서버2 라우터1[라우터] --10.0.0.4--o 서버3 라우터1[라우터] --10.0.0.5--o 서버4 end subgraph 회원1의 라우터 내부망 152.242.291.281 direction TB 공유기 --192.168.0.3--o 컴퓨터1 end 컴퓨터1 --> 공유기 --> 라우터1 --> 서버1 end
flowchart
subgraph 공인망
direction TB
subgraph "기업의 내부망 165.232.123.5"
direction TB
라우터1[라우터] --10.0.0.2--o 서버1
라우터1[라우터] --10.0.0.3--o 서버2
라우터1[라우터] --10.0.0.4--o 서버3
라우터1[라우터] --10.0.0.5--o 서버4
end
subgraph 회원1의 라우터 내부망 152.242.291.281
direction TB
공유기 --192.168.0.3--o 컴퓨터1
end
컴퓨터1 --> 공유기 --> 라우터1 --> 서버1
end
전체적인 구조는 위와 같다.
컴퓨터 1 –> 개인의 공유기 –> 공인망 –> 기업의 라우터 –> 서버1
회원1의 내부망 기준에서는 아웃바운드, 기업의 입장에서 인바운드를 통해 외부망과 통신하는 예제를 살펴봤습니다.
실습
내부망 구축과 관련된 실습은 Proxmox 내부망 구축하기 글을 참고하세요. 이 글에서는 iptables 를 조금 더 쉽게 사용할 수 있도록 한 nftables를 통해 내부망을 구축하는 방법에 대해 알아봅니다.
Domain
지금까지는 IP 주소를 통해 컴퓨터간 통신을 하는 예제를 보았습니다. 다만 IP주소는 기억하고 사용하기 어렵기 때문에, 도메인으로 대체하게 되었습니다. 이를 위해서는 도메인과 IP를 매핑시켜주는 서버가 필요한데요, 이를 DNS서버라고 합니다.
DNS 서버에는 4가지 분류가 있습니다.
- DNS recursive resolver
- Root DNS
- TLD DNS
- authoritative DNS
flowchart 컴퓨터 --example.com--> Resolver subgraph DNS direction LR Resolver[DNS Resolver] --> RootDNS --> com --> example.com subgraph TLD DNSs com[.com DNS] net[.net DNS] org[.org DNS] end subgraph Authoriative DNSs example.com example.net example.org end end
flowchart
컴퓨터 --example.com--> Resolver
subgraph DNS
direction LR
Resolver[DNS Resolver] --> RootDNS --> com --> example.com
subgraph TLD DNSs
com[.com DNS]
net[.net DNS]
org[.org DNS]
end
subgraph Authoriative DNSs
example.com
example.net
example.org
end
end
컴퓨터는 처음에 DNS Resolver 로 example.com에 대한 IP주소를 요청합니다. Resolver 에 캐시가 존재한다면 즉시 리턴될 수 있지만, 아니라면 Root DNS로 넘어간 후, 각 TLD의 DNS로 넘어간 후 각 도메인의 DNS로 넘어가 해당 도메인에 대한 레코드를 조회할 수 있습니다.
A레코드를 통해 IPv4 주소를 가르킬 수 있고, AAAA레코드를 통해 IPv6 주소를 가르킬 수 있습니다.
💡 MX 레코드를 사용하면 [email protected] 과 같은 커스텀 도메인 이메일을 만들 수 있다.
이러한 과정을 통해 모든 도메인의 IP 주소를 모두 알아낼 수 있습니다. 실제로 이를 실행하려면 터미널에서 nslookup
명령을 사용할 수 있습니다.
도커 네트워크
도커는 가상의 내부망을 구축하여 각 컨테이너에 IP를 할당하게 된다. 도커 네트워크를 생성하면 자동으로 가상의 통신 장비와 브릿지, DNS가 추가되며, 물리 NIC를 대신해서 가상 네트워크 인터페이스가 시스템에 생성된다.
도커 네트워크를 먼저 생성하자. 브릿지를 하나 만드는데, 10.0.0.0/24 범위를 사용하고, 게이트웨이(라우터)주소는 10.0.0.1 로 하겠다는 뜻이다.
docker network create --driver bridge --subnet 10.0.0.0/24 --gateway 10.0.0.1 second-bridge
그 후 containerA, B, C를 생성한다
docker run -it --name containerA devwikirepo/pingbuntu bin/bash
docker run -it --network second-bridge --name containerB devwikirepo/pingbuntu bin/bash
docker run -it --network second-bridge --name containerC devwikirepo/pingbuntu bin/bash
flowchart RL subgraph dockerNetwork subgraph second-bridge bridge2[bridge] DNS containerB containerC end subgraph "default" bridge1[bridge] containerA end end
flowchart RL
subgraph dockerNetwork
subgraph second-bridge
bridge2[bridge]
DNS
containerB
containerC
end
subgraph "default"
bridge1[bridge]
containerA
end
end
💡 기본적으로 생성되는 default 네트워크에는 DNS가 없다.
💡 이때 생성된 DNS는 일반적인 도메인을 조회하기 위해 사용하는 것이 아닌, 내부망에서 사설 도메인을 사용하기 위해 사용하는 DNS로, 각 컨테이너의 IP대신 이름을 사용할 수 있도록 해 준다.
위와 같이 설정되어 있을 것이다. 이때 같은 네트워크에 있지 않은 컨테이너 간에는 소통이 불가능하다.
# containerA
ping 10.0.0.2 #불가능
ping 10.0.0.3 #불가능
flowchart RL subgraph dockerNetwork second-bridge ~~~ default subgraph second-bridge bridge2[bridge] DNS containerB containerC end subgraph "default" bridge1[bridge] containerA end containerA --10.0.0.2--x containerB containerA --10.0.0.3--x containerC end
flowchart RL
subgraph dockerNetwork
second-bridge ~~~ default
subgraph second-bridge
bridge2[bridge]
DNS
containerB
containerC
end
subgraph "default"
bridge1[bridge]
containerA
end
containerA --10.0.0.2--x containerB
containerA --10.0.0.3--x containerC
end
반면에, 같은 네트워크에 있는 B와 C는 IP주소 및 컨테이너 이름(DNS가 있을 때)을 통해 통신할 수 있다.
# containerB
ping 10.0.0.3
ping containerB ## 두 명령은 동일하게 작동한다.
flowchart TB subgraph dockerNetwork default ~~~ second-bridge subgraph second-bridge DNS containerB containerC end subgraph "default" containerA end containerB <--> containerC end
flowchart TB
subgraph dockerNetwork
default ~~~ second-bridge
subgraph second-bridge
DNS
containerB
containerC
end
subgraph "default"
containerA
end
containerB <--> containerC
end
도커 컨테이너와 포트포워딩
docker run -d -p 8004:3000 --name greenColorApp --env COLOR=green devwikirepo/envnodecolorapp
위와 같이 외부망 포트 8004번을 컨테이너 3000번에 연결시킬 수 있다.
flowchart subgraph HOST subgraph DockerNetwork bridge --8004:3000--o greenColorApp end end
flowchart
subgraph HOST
subgraph DockerNetwork
bridge --8004:3000--o greenColorApp
end
end
위와 같이 호스트 8004번 포트로 요청이 오면, greenColorApp
컨테이너로 3000번 포트로 전달된다. 라우터의 포트포워딩 테이블과 똑같이 작동하는 것이다. 브라우저로 localhost:8004
에 접근하면 초록 페이지가 나타난다.
냥 이치 니 산 냥 아리가또~에 답글 남기기 응답 취소