네트워크 계층의 ICMP 프로토콜부터 이어서 시작합니다!
다음 글 예고..🫠 VMware에서 Host-only, NAT, Bridge 네트워크 변경하는 법을 알아보고자 합니다.(덤으로 테트리스???)
Ⅰ. 개요
네트워크 계층의 ICMP(Internet Control Message Protocol), IGMP(Internet Group Management Protocol)프로토콜이 있다. ICMP는 패킷을 주고 받는 과정에서의 오류 메시지에 대한 프로토콜이고 IGMP는 멀티캐스트에 관여하는 프로토콜이다. 전송 계층은 크게 TCP(Transmission Control Protocol)과 UDP(User Datagram Protocol)이 있다. TCP는 3-way-handshake를 기반으로 한 신뢰성있는 연결 지향형 프로토콜이고 UDP는 빠른 속도가 장점인 비연결 지향형 프로토콜이다. 네트워크 서비스로 NAT(Network Address Translation)이 있는데, 이는 내부 IP와 외부 IP를 정의하고 있다. 다음으로 DHCP(Dynamic Host Configuration Protocol)은 이전 게시글에서도 설명했지만 IP 주소 할당 방식을 정의하고 있다.
Ⅱ. 프로토콜(네트워크, 전송 계층 중심으로)
네트워크 계층 프로토콜(Protocol)
이전 게시글에 이어 네트워크 계층의 ICMP(Internet Control Message Protocol) 프로토콜을 설명하자면, 호스트 서버와 게이트웨이(라우터) 사이에서 메시지를 제어하고 오류를 알려준다. ICMP를 사용하는 대표적인 명령어가 있다.
ping 10.10.10.2
위에 ping 명령어 다음 연결이 되고 있는지 알아보고 싶은 주소(IP 주소, 도메인 이름 주소 모두 가능)를 입력하면 그 아래 사진처럼 정상적으로 연결이 되고 있을 때 저런 메시지가 나온다. 만약, 정상적으로 연결될 수 없다면 오류 메시지가 나온다. ping은 임시 패킷을 보내 서버의 응답 상태를 알아볼 수 있다.
IP는 비연결형 프로토콜로서 패킷이 확실히 전송된다는 보장이 없기 때문에, 라우터나 노드(호스트) 등에서 오류가 생겨 목적지까지 도달하지 못할 경우엔 송신측의 상태를 알려줄 필요가 있다. 이 때문에, ICMP 프로토콜로 송신받는 여러 라우터의 상황과 목적지 노드의 상황을 진단한다. ICMP 프로토콜은 IP 프로토콜 위에 동작하는 상위 계층(전송 계층)의 TCP, UDP 프로토콜과는 별개지만, 마찬가지로 IP 프로토콜 위에서 작동하며, 저번 게시글의 IP 프로토콜 TTL(Time To Live)와 관련이 있다. ICMP 패킷 구조에서 알아둘 부분은 Checksum이다. Checksum은 패킷의 오류를 감지하는 역할이다. 1의 보수를 계산해서 Carry 비트 연산법을 반영하여 최종 Checksum을 계산한다.
※ Checksum의 계산법과 Carry 비트 연산법은 아직 이해를 못해 다른 게시글을 참조바란다.

리눅스 및 네트워크 강의 교안 참조
ICMP는 크게 오류 통지를 위한 오류 메시지와 진단용 문답 메시지가 있다. ICMP Echo Request 메시지는 송신측의 전송 패킷이 목적지 노드나 라우터에 도착했는지 확인하는데 사용된다. 송신측 노드(요청을 보낸 호스트)는 목적지 노드에 'ICMP Echo Request 메시지'를 송신하고, 목적지 노드로부터 'ICMP Echo Reply 메시지'가 회신되면 패킷이 무사히 전송되었다고 인식한다. ICMP Destination Unreachable 메시지는 라우터가 특정 노드의 패킷을 목적지에 보내지 못할 경우, 송신 노드에 'ICMP Destination Unreachable 메시지'를 보낸다. '여기엔 목적지까지 전송되지 못한 이유가 포함된다.' 목적지 노드의 IP 주소 경로를 찾아내지 못한 라우터는 송신측 라우터로 이 메시지를 되돌려 보내 최초 송신 노드는 이 메시지를 해석해서 패킷이 목적지에 도착하지 못했음을 파악한다.
※ Echo는 유닉스 계열 운영체제에서 터미널에 문자열을 출력하는 명령어이다. 리눅스(ubuntu)도 당연히 유닉스 계열이므로 이 명령어가 있는데 단순히 문자열 출력에서 쓰이는 것만이 아닌 셸 스크립트에서 자주 사용하게 된다.
ICMP Redirect 메시지는 라우터가 송신측 노드에 적합하지 않은 경로로 설정되어 있는 경우 목적지 노드에 대한 최적화된 경로를 다시 지정해주는 메시지를 보낸다. ICMP Time Exceeded 메시지는 이전에 IP 프로토콜의 TTL을 활용하여 패킷이 네트워크 사이에서 무한정 돌아다니지 않게 하기 위해, TTL이 0이 될 경우 'ICMP Time Exceeded 메시지'를 되돌려 보내고 패킷을 폐기한다. 패킷은 최초 노드로부터 라우터를 하나 지날 때마다 1씩 줄어들고 최종 목적지 노드에 도착하기 전에 0이 되면 패킷이 제대로 전달되지 못한 것이다.

리눅스 및 네트워크 강의 교안 참조
ICMP Source Quench 메시지는 저속 광역 회선 등을 사용할 경우 WAN 쪽에 특정 라우터에서 병목 현상이 발생할 수 있는데, 이 집중을 완화하기 위해 송신측 큐 값이 '0'으로 남아 송신 불능 상태가 되면 'ICMP Source Quench 메시지'를 송신측 노드에 보내고 송신측은 이 메시지를 해석하여 회선의 어딘가 혼잡하니 송신 패킷 양을 제어하게 된다.

리눅스 및 네트워크 강의 교안 참조
※ 저속 광역 회선이란? WAN 규모 단위의 통신망으로 주로 음성 데이터를 보내는 데 사용된다. VoIP(Voice over IP) 이용되는데 자세한 개념은 찾아보길 권장한다.
다음으로 IGMP(Internet Group Management Protocol)프로토콜이 있다. 멀티캐스트 그룹을 관리하는 프로토콜로 멀티캐스트를 얘기하기 전에 유니캐스트와 브로드캐스트를 알아야 한다. 유니캐스트는 한 호스트에서 다른 호스트로 전송하는 일 대 일의 관계이다. 일반적인 IP 데이터 전송은 모두 유니캐스트이다. 우리(일반 사용자)가 네이버나 구글에 접속하는 과정이 유니캐스트라고 보면 된다. 브로드캐스트는 호스트에서 IP 네트워크의 전체 호스트로 데이터를 전송한다. 이전 게시글에서 IP 프로토콜의 클래스 개념을 생각해보면, 각 클래스의 해당되는 '예를 들어, 공유기로 연결된 모든 장치' 네트워크 대역 모두에게 데이터가 전송된다. 일반적인 브로드캐스트는 '255.255.255.255'이고 특정 네트워크에 브로드캐스팅하는 것을 다이렉트 브로드캐스팅이라고 하는데, '211.32.34.0' 네트워크 대역에 데이터를 전송하려면 목적지 주소를 '211.32.34.255'로 지정하면 된다. 즉, 특정한 하나의 IP에 전송하는 것이 아닌, 광범위한 데이터 전송이다. 주로 ARP(Address Resolution Protocol)가 MAC 주소를 찾을 때 사용하거나 이후에 다룰 DHCP(Dynamic Host Configuration Protocol)가 동적으로 IP 주소를 할당할 때 사용된다. 멀티캐스트는 이 유니캐스트와 브로드캐스트의 중간 형태로서 송신하는 하나의 호스트에 특정한 호스트를 묶어서 전송한다. 이 특정한 호스트를 묶은 것이 멀티캐스트 그룹인데 이 그룹에 속한 모든 호스트가 데이터를 전달받기 때문에 효율이 높다.
2. 전송 계층 프로토콜(Protocol)
이 계층에서 가장 중요한 프로토콜은 TCP(Transmission Control Protocol)과 UDP(User Datagram Protocol)가 있다. 이 두 프로토콜을 설명하기 전에 이전 게시글에서 예시로 든 '시골에 계신 할머니나 할아버지에게 편지를 보낸다.'라는 상황을 상상해보자. 나는 시골에 계신 할머니나 할아버지에게 편지를 보내기 위해 편지를 작성하게 될 것이다. 이 편지는 처음엔 작은 종이에 볼펜으로 적은 글이었지만, 편지지로 포장하고 우체통에 넣게 될 것이다. 이때 편지는 패킷으로 편지가 편지지에 감싸듯 안전한 편지 전달을 위한 정보가 점점 더해가는 것이 OSI 7계층에서 각 계층의 프로토콜의 역할이다. 그리고 우체통은 편지가 전달되는 첫 과정으로 패킷이 최초의 물리 계층 랜카드에서 출발하듯 우체통을 랜카드로 생각해도 좋다. 이때, 우체국은 게이트웨이(라우터)가 될텐데 편지는 각 게이트웨이를 지나다니며 최종 목적지로 전달될 것이다. 우체국에서 이 편지가 일반 우편으로 갈지 빠른 전달을 위해 등기 방식으로 갈지 보낼 방법을 정하면서 우표를 붙이게 될텐데, 우표가 바로 TCP와 UDP가 된다.
이어서 TCP를 설명해보자면, TCP는 패킷을 전달받는 상대방이 누구인지 정확히 알고 받았다는 걸 보낸 사람에게 확인시켜주는 방식(3-way-handshake)으로 통신하는 걸 의미한다. 그래서 연결 지향형(Connectionoriented) 프로토콜로 불리며, 데이터 흐름을 관리하고 데이터가 정확한지 검증하며 통신한다. 장점으로 신뢰성이 높고 데이터 제어 흐름, 데이터 체크섬, 시간 초과와 재전송 등이 있지만, 단점으로 속도가 느릴 수 있다. 반면, UDP는 일단 보내놓고 제대로 받았는지 응답을 받는 확인 과정을 거치지 않는다(응답을 요청할 순 있지만, 제대로 응답이 돌아온다는 보장을 할 수가 없다.). 보내기만 하고 끝이라는 점에서 비연결 지향형 프로토콜이다. 송신 시스템과 목적지 시스템 사이에서 상호 통신이 이루어지지 않기 때문에, 전송되는 과정에서 데이터를 일부 손실되더라도 재전송을 요구하지 않는다. 애초에 비연결이기 때문에, 손실된 데이터 정보를 알 수 없다. 대신, 장점은 굉장히 속도가 빠르고 네트워크 부하가 감소한다는 것이지만, 데이터가 손실될 수 있고 비신뢰성은 단점일 수 있다. 속도가 빠르기 때문에, 영상 스트리밍, 게임과 같이 실시간 작업에 좋을 때가 있기 때문에, TCP와 UDP는 각각 용도에 따라 활용될 수 있다. 어떤 전송 방식이 특별히 좋다라고 할 수 없다.
※ 두 전송 방식 중 어떤 전송 방식을 선택할지 헤더에 동작 방식을 정의해줘야 한다.
TCP의 중요한 개념 중 하나인 '3-way-handshake'는 클라이언트와 서버가 통신할 때 클라이언트는 접속해도 괜찮을지 서버에게 SYN(Synchronize)를 보낸다. 제대로 전달받은 서버는 SYN과 함께 ACK(Acknowledgement)를 같이 보내서 응답한다. 응답을 받은 클라이언트는 서버와 연결하며 잘 연결되었다는 의미로 ACK를 서버에게 다시 보낸다. 이렇게 3단계를 거치는데, 예를 들어, 친구의 집에 전화를 걸어서 친구가 있는지 확인하는 것이 1단계, 친구가 있다는 것을 응답 받은 것이 2단계, 친구가 전화를 바꿔 나와 통화할 때 내가 누구인지 친구에게 알리는 것을 3단계라고 생각하면 좋다. 그 후 전화를 끊기 전까지 지속적으로 연결이 유지된다. 이 과정을 도식으로 보여주자면,

리눅스 및 네트워크 강의 교안 참조
이렇게 된다. 연결을 해제 하려고 하면 FIN(Finish)를 클라이언트가 서버에게 요청한다. 서버는 ACK를 보내 화답하고 FIN을 이어서 보낸다. 전달받은 클라이언트는 다시 서버에게 ACK를 보내 서로의 연결은 종료된다. 이 과정도 마찬가지로 도식으로 살펴보자면,

리눅스 및 네트워크 강의 교안 참조
이렇게 된다. 여기서 SYN은 연결 요청에 관한 정보로 패킷에 TCP 프로토콜 부분에 들어갈텐데, 1이면 연결 요청과 설정으로 연결이 진행됨에 따라 1씩 더해진다. ACK은 통신 상대의 패킷 순서에 대한 값이다. FIN은 1이면 TCP 연결을 종료한다는 의미로 클라이언트와 서버가 연결을 종료할 때 패킷에 이 번호를 담는다.
※ 연결 종료 과정이 왜 있을지 의문일 수 있다. 네이버처럼 대규모의 서비스를 제공하는 서비스 제공자는 대량의 서버를 보유해서 우리에게 원활한 서비스를 제공하는데, 그래도 서버의 자원은 유한하다. 항상 모든 연결을 유지하고 열어놓게 되면 당연히 서버의 리소스는 한계를 맞이할 것이기 때문에, 필요할 때마다 연결하고 종료해서 메모리를 효율적으로 관리하기 위해 종료 과정이 필요하다.

운영체제 안에서 작동하는 프로세스 혹은 서버의 상태를 알아보는 명령어 'netstat'가 있다. 위에서 '-anp'는 옵션인데 'a'는 전체를 의미하고 'n'은 IP 주소를 의미하며, 'p'는 프로세스를 의미한다. TCP의 3-way-handshake를 설명하면서 나왔던 클라이언트와 서버의 연결 과정에서 LISTEN을 알아두면 좋다. LISTEN은 서버가 실행되고 외부의 요청에 응답을 할 수 있는 상태로 Local Address에서 '0.0.0.0:80'으로 요청이 들어온 경우에 접속을 허용한다는 의미이다. 여기서 '0.0.0.0'은 모든 IP 주소를 뜻하고 그 위에 바로 '127.0.0.1'은 자신의 IP 주소로 보통 로컬호스트(Local Host)라고 부른다. 맨 왼쪽에 보면 익숙한 용어를 볼 수 있는데 바로 TCP와 UDP이다. 여기에 각 서버가 어떻게 연결할지에 대한 동작 방식을 나타내주고 있는데, TCP와 UDP는 알겠는데 숫자 6이 붙은 경우는 생소할 것이다. TCP와 TCP6의 차이는 주소 체계가 IPv4인지 IPv6인지를 구분하는 것이다. 그래서 TCP는 우리가 익숙한 '0.0.0.0' IP 주소로 되어 있지만, TCP6는 ':::'으로 되어 있다.
'0.0.0.0'이 모든 IP 주소를 의미하는 것처럼 ':::'는 IPv6에서 모든 IP 주소를 의미한다. 그리고 LISTEN 아래에 ESTABLISHED가 보일텐데 이건 접속이 성공하여 연결이 된 상태를 의미한다. 추가적으로 '0.0.0.0:80'에서 ':' 다음의 숫자 80은 포트(Port) 번호를 나타낸다. 포트 번호는 현재 운영체제에서 열린 여러 서버 중 그 어떠한 서버도 중복될 수 없다. 즉, 하나의 서비스에는 하나의 포트 번호만 가능하다. 보통 웹사이트의 모든 서비스는 기본 포트를 80번으로 하고 있으며, 각 프로토콜 별로, 서버별로 기본 포트가 정해져 있는 경우가 있어 알아두면 유용하다. 프로토콜 포트 번호는 0번부터 40번 사이로 정의되어 있다. 클라이언트의 경우에도 포트 번호를 가지고 있을텐데 브라우저가 연결 시 자동(겹치지 않게)으로 할당해준다. 가장 아래에 IP 주소가 안보이는 경우는 운영체제 시스템 내부에서 동작하는 프로세스를 의미하고 맨 왼쪽에 'unix'를 볼 수 있을텐데 이 동작 방식이 시스템 내부 프로세스를 의미한다고 보면 된다. 이 'unix'로 된 프로세스들이 굉장히 많은데, 윈도우에서도 부팅하면 내부적으로 돌아가는 프로세스들이 많다. 시작 프로그램을 알고 있다면 조금 더 이해가 용이할텐데, 공유 폴더 기능을 수행해주는 프로세스, 윈도우 화면을 보이게 하거나, 마우스나 키보드로 제어를 용이하게 해주는 등의 내부 프로세스가 리눅스에서 'unix'로 보이는 부분이라고 생각하면 된다.
※ 만약, 서비스가 정상 작동 중이고 정확한 포트 번호로 접근했는데 서버에 접근할 수 없다면 방화벽을 확인해보자!

※ 리눅스 명령어의 특성과 관련되어 있는데, '|' 이런 파이프 기호로 명령어의 연속 실행이 가능하다. 그래서 netstat -anp 명령어 다음에 '|' 기호를 붙이고 검색 명령어인 grep과 검색어를 입력해주면 이렇게 운영중인 서버나 작동하는 프로세스 중 해당하는 것만 출력해준다.
프로세스 이야기가 나왔기 때문에 관련된 명령어를 조금 더 소개하자면, 'ps -ef'가 있다. 옵션 'e'는 모든 프로세스 정보, 'f'는 더 자세한 정보를 보여준다.

이렇게 보이는 데 여기서 PID를 알면, 프로세스를 종료시키는 명령어를 이용할 수 있다. 'kill -9 프로세스ID'를 입력하게 되면 해당 프로세스를 종료시킬 수 있고 여기서 '9' 옵션은 강제로 죽인다.
※ 'w' 명령어로 접속 정보도 확인해볼 수 있다!
Ⅲ. 네트워크 서비스
NAT(Network Address Translation)
이전에 네트워크를 처음 게시할 때 내부 IP와 외부 IP에 대한 이야기를 했다. 내부 IP는 공유기를 통해 연결된 같은 장치끼리 공유하는 IP 주소이고 외부 IP는 네이버, 구글과 같은 외부의 서비스를 이용하기 위해 필요한 IP 주소였다. 이 내부 IP 주소를 외부 IP 주소로 매핑(Mapping)시켜주는 방식이 있는데 바로 NAT이다. NAT는 하나의 내부 IP 주소와 하나의 외부 IP 주소를 일 대 일로 매핑시키는 Static NAT와 여러 개의 내부 IP 주소와 여러 개의 외부 IP 주소를 동적으로 매핑시키는 Dynamic NAT가 있다. Static NAT는 변경시킬 주소가 이미 지정되어 있기 때문에, '이 내부 IP는 이 외부 IP다.'라고 알 수 있기 때문에, 외부에서도 내부로 통신이 가능하다. 그래서 서비스를 제공하는 입장에서는 외부에서 외부 IP 주소로 접근할 때 서버에 연결되어 서비스가 제공되어야 하므로 이 방식을 사용한다. 반면, Dynamic NAT는 외부 IP Pool을 만들어 놓고, 그 중 사용하지 않는 IP를 동적으로 매핑한다. 외부 IP의 수가 내부 IP 수보다 적을 경우에 일 대 일로 매핑이 안되므로 이 방식을 사용하며, 외부 IP 수가 내부 IP 수보다 적기 때문에 이미 외부 IP가 사용 중이라면 외부에서 들어온 다른 사설(내부) IP와 매핑될 수 없다.

2. DHCP(Dynamic Host Configuration Protocol)
DHCP 서버는 이미 예전에도 설명한 적 있는데, 특정(여러) 장치가 같은 네트워크 대역에 소속되기 위해 IP 주소를 요청받고 할당해주는 역할을 한다. 예를 들어, 노트북을 사용해서 카페 WIFI에 연결한다면 연결 과정 동안 DHCP 서버가 있는지 브로드캐스팅으로 물어본다. 수신된 DHCP 서버는 자신의 IP 주소를 알려주며, 할당해 줄 수 있는 IP 주소를 알려준다. 브로드캐스팅 과정으로 진행되기 때문에 같은 네트워크 대역에 소속된 모든 장치는 이 메시지를 수신받을 수 있다. 그렇게 할당받을 수 있는 IP 주소를 알게 되면 할당해 달라고 요청하고 DHCP 서버는 할당을 하면서 관련된 네트워크 정보를 전달해준다. 이 과정을 도식으로 표현하자면 아래와 같다.

후기
거의 반나절에 걸쳐 네트워크, 네트워크 유형, OSI 7게층, 데이터 링크, 네트워크, 전송 계층의 프로토콜을 다뤄보았습니다. 아직도 못다룬 부분이 정말 많아 네트워크는 엄청난 분야구나라는 걸 다시금 느낍니다....😔 아쉽기도 한데 짧은 시간안에 다 이해하고 외울 수 있는 부분이 아니라 일단 이 정도로 만족하고 추가적으로 공부를 진행하며 채워나가려고 합니다.🙂
Log in