기본 개요
- 모던 환경에서 네트워킹은 중심적 역할을 수행한다.
- 여기에는 앱 설치, 웹 검색, 메일이나 소셜 미디어 사용 같은 작업부터 원격 시스템 작업(로컬 네트워크를 통해 연결하는 임베디드 시스템부터 클라우드 공급자의 데이터 센터에서 실행되는 서버까지)도 포함된다.
- 네트워크에는 변화하는 분야와 계층이 많기 때문에, 문제가 발생하면 하드웨어 때문인지 소프트웨어 스택에서 비롯된 문제인지 파악하기 어려울 수 있다.
- 리눅스 네트워킹이 다루는 또 다른 문제는 추상화에서 비롯된다.
- 이 장에서 다룰 많은 도구들은 높은 수준의 사용자 인터페이스를 제공하기 때문에 실제로 원격 시스템에서 실행되는 파일이나 애플리케이션이 로컬 머신에서 접근하거나 조작할 수 있는 것으로 보인다.
- 원격 리소스가 마치 로컬에 있는 것처럼 보이게 하는 추상화는 유용한 기능이지만 결국 이 모든 것의 근간은 유선과 무선을 통해 이동하는 비트라는 사실을 잊어서는 안된다.
- 문제를 해결하거나 테스트할 때는 이 점을 염두에 두어야 한다.
TCP/IP 스택
- 각 계층은 자신의 바로 위와 아래에 있는 계층만 인식하고 통신할 수 있어야 한다.
- 데이터는 패킷으로 캡슐화되며 각 계층은 일반적으로 해당 기능과 관련된 정보를 포함한 헤더로 데이터를 래핑한다.
- 따라서 데이터를 보내려는 앱은 최상위 계층과만 직접 상호 작용하고, 최상위 계층데이터에서 헤더를 추가해 다시 아래 스택으로 내려보내는 식이 된다.
- 반대로 앱이 데이터를 수신할 때는 이 데이터가 먼저 최하위 계층에 도착하고 각 계층이 차례대로 찾은 헤더 정보를 기반으로 처리하는 페이로드를 상위 계층에 전달한다.
링크 계층
- 링크 계층은 바이트, 유선, 전자기파, 디바이스 드라이버, 네트워크 인터페이스 같은 하드웨어, 혹은 하드웨어에 가까운 항목에 관한 것이다.
- 관련 용어는 아래와 같다.
- 이더넷(ethernet) : 유선을 사용해 기기를 연결하는 네트워킹 기술로 근거리 통신망(LAN)에서 자주 사용된다.
- 무선 : 와이파이라고도 알려진 통신 프로토콜 및 방법의 한 종류로 유선을 사용하지 않고 전자 기파를 사용해 데이터를 전송한다.
- MAC 주소 : MAC은 각 하드웨어마다 고유한 48bit 식별자로서, 각 기기를 식별하는 데 사용된다.
- 일반적으로 24 bit를 조직 고유 식별자로 사용해 제조업체 정보를 인코딩한다.
- 인터페이스 : 네트워크 연결. 이는 물리적 인터페이스일 수도 루프백 인터페이스
lo
같은 가상 인터페이스 일 수도 있다.
네트워크 인터페이스 컨트롤러
- 하드웨어 장비의 필수 요소 중 하나는 NIC(Network Interface Controller, 네트워크 인터페이스 카드)이다.
- 네트워크의 일부가 된 NIC은 전송하려는 바이트의 디지털 표현을 전기 혹은 전자기 신호로 바꾼다.(수신은 그 반대)
- 시스템에서 사용 가능한 NIC에 대한 정보를 쿼리하기 위해서는 전통적으로 쓰였던 ifconfig 명령을 사용한다.
- 이와 동일한 작업을 수행하는 현대적인 접근 방식은 ip 명령을 사용하는 것이다.
ip link show
==ifconfig
- 이러한 명령을 통해 출력된 플래그들의 의미는 netdevice 메뉴얼 페이지에 문서화 되어 있다.
주소 결정 프로토콜(ARP)
- MAC 주소를 IP 주소에 매핑한다.
- 어떤 의미에서는 링크 계층을 그 위의 계층인 인터넷 계층과 연결하는 것이다.
arp
커맨드를 사용하면 매핑된 캐시를 보여준다.- ==
ip neigh
- ==
- 무선 디바이스를 표시하거나 구성하거나 문제를 해결하려 할 때도
iw
명령을 사용하면 된다.- 예를 들어 이미 무선 NIC 이름을
wlp1s0
임을 알고 있다면 아래와 같이 쿼리할 수 있다. ```bash iw dev wlp1s0 info
- 예를 들어 이미 무선 NIC 이름을
iw dev wlp1s0 link # 라우터와 트래픽 관련 정보 수집 쿼리
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
## 인터넷 계층
- 인터넷 계층은 네트워크의 한 시스템에서 다른 시스템으로 패킷을 라우팅하는 것과 관련 있다.
- 인터넷 계층의 설계는 사용 가능한 네트워크 인프라가 신뢰할 수 없으며 참여자가 자주 변경된다고 가정한다.
- 인터넷 계층은 최선의 전달을 제공하고 모든 패킷을 독립적으로 취급한다.
- 그 결과 상위 계층(전송 계층)은 패킷의 순서, 재시도, 배달 보장을 포함한 신뢰성 문제를 포함한다.
- 이 계층에서 기기를 논리적으로 고유하게 식별하기 위해 전 세계적으로 압도적으로 많이 사용되고 있는 프로토콜이 바로 IP이며 IP는 버전4와 6가 있다.
### IPv4
- TCP/IP 통신에서 엔드포인트 역할을 하는 호스트나 프로세스를 고유하게 식별하는 32bit 숫자를 정의한다.
- 32비트를 마침표로 구분된 4개의 8bit 조각으로 분할하며, 각 조각은 옥텟(octet)이라 부른다.(0~255)
- RFC 791을 비롯해 관련 IETF 사양에 정의된 것처럼 IP 헤더에는 많은 필드가 존재한다.
- 이는 내 블로그의 네트워크 관련 CS 카테고리에 잘 정리되어 있다.
- 오늘날은 CIDR이 IP 할당과 관련된 유일한 방법이다.
- 해당 범위에 얼마나 많은 IP가 있는지를 파악하기 위해서 CIDR 범위를 계산을 할 때는 다음을 사용하면 된다.
- 온라인 도구
- mapcidr, cidrchk 같은 커맨드라인 도구
- 다음과 같은 예약된 IPv4 주소도 중요하며 알아둬야 한다.
- 127.0.0.0 : 이 서브넷은 로컬 주소용으로 예약되어 있으며 가장 중요한 것은 루프백 주소인 127.0.0.1이다.
- 169.254.0.0/16 : 이들은 링크 로컬 주소로 전송된 패킷이 네트워크의 다른 부분으로 전달되지 않아야 함을 의미한다. 아마존 웹 서비스 같은 일부 클라우드 공급자는 이 주소를 특수 서비스에 사용한다.
- 224.0.0.0/24 : 이 범위는 멀티캐스트용으로 예약되어 있다.
- RFC 1918에는 사설 IP 범위가 정의돼 있다.
- 사설 IP 범위는 해당 IP 주소를 공용 인터넷에서 라우팅할 수 없음을 의미한다.
- 따라서 내부적으로(회사 내부) 지정하는 편이 안전하다.
- 또 다른 흥미로운 IPv4 주소는 0.0.0.0이다. 라우팅이 불가능한 주소이며 상황에 따라 사용 사례와 의미가 다르다.
- 서버 관점에서는 0.0.0.0이 시스템에 있는 모든 IPv4 주소를 의미한다.
- 이는 "알려준 IP로 바뀔 때까지 송신지 선택을 위해 모든 사용 가능한 IP주소에서 수신 대기하라"라는 의미이다.
### IPv6
- TCP/IP 통신에서 엔드포인트 식별용으로 쓰이는 128bit 숫자이다.
- 각각 16비트로 구성된 8개 그룹을 콜론(:)으로 구분하는 16진수 표현식을 사용한다.
- 이런 IPv6 주소를 짧게 줄이기 위한 몇 가지 규칙이 있다.
- 선행되는 0을 제거하거나 연속되는 0의 섹션을 압축해 2개의 콜론(::)으로 대체하는 등이다.
- IPv6에서도 다수의 특별 주소, 예약 주소가 존재한다.
- IPv4와 IPv6는 호환되지 않는다는 점에 유의해야 한다.
- 즉 휴대폰 같은 종단 디바이스부터 라우터, 서버 소프트웨어에 이르는 모든 네트워크 참여 디바이스가 IPv6를 지원해야 한다.
### 인터넷 제어 메시지 프로토콜(ICMP)
- RFC 792에는 에러 메시지와 가용성 같은 운영 정보를 보내는 저수준 구성요소에 사용되는 인터넷 제어 메시지 프로토콜이 정의돼 있다.
- `ping`으로 웹 사이트의 도달 가능성을 테스트해 ICMP의 동작을 살펴보자
- 또는 gping을 사용해 동시에 여러 대상을 ping하고 커맨드라인에 그래프를 그릴 수도 있다.
### 라우팅
- 리눅스에서 네트워크 스택의 일부는 라우팅과 관련이 있다.
- 즉 패킷을 보낼 위치를 패킷별로 결정한다.
- 라우팅 테이블을 조작하는 데(에를 들어 특정 조건에서 패킷을 재라우팅하거나 방화벽을 구현하기 위해) 널리 사용되는 도구인 iptables는 패킷을 가로채고 조작하기 위해 netfilter를 사용한다는 점이다.
- 다음과 같이 라우팅 정보를 쿼리해서 출력하는 방법을 알아보자
```bash
sudo route -n
- 앞서의 route 명령에서 표로 출력된 필드의 자세한 의미는 다음과 같다.
- Destination : 수신지의 IP 주소 0.0.0.0은 지정되지 않거나 알 수 없음을 의미하며 잠재적으로 게이트웨이로 보낼 수 있다.
- Gateway : 동일한 네트워크에 있지 않은 패킷의 경우 게이트웨이 주소
- Genmask : 사용된 서브넷 마스크
- Flags : UG는 네트워크가 동작 중이며 이것이 게이트웨이임을 의미한다.
- Iface : 패킷이 사용할 네트워크 인터페이스
- 이보다 현대적인 방법은 다음과 같이
ip
를 사용하는 것이다.1
sudo ip route
전송 계층
- 이 계층은 전부 엔트포인트 간의 통신 특성에 관한 것이다.
- 여기에는 연결 지향 프로토콜과 비 연결 프로토콜이 있는데, 이들의 신뢰성, QoS, 순차 배송은 중요한 영역이다.
포트
- 이 계층의 핵심 개념 중 하나는 포트이다.
- 이 계층에서 어떤 프로토콜이 사용되든 그 각각은 포트가 필요하다.
- 포트란 IP주소에서 사용 가능한 서비스를 식별하는 고유한 16비트 숫자이다.
- 포트는 아래와 같은 종류로 나뉜다
- 잘 알려진 포트 (0번~1023번): SSH 서버나 웹 서버 같은 데몬용이다. 이들 중 하나를 사용하려면 높은 권한이 필요하다.
- 등록된 포트(1024번~49151번) : 이들은 IANA이 공개적으로 문서화된 프로세스를 통해 관리한다.
- 한시적 포트(49152번 ~ 65535번) : 등록할 수 없는 포트이다. 이들은 한식적으로 포트를 자동으로 할당하는 데 사용되거나 개인 서비스에도 사용될 수 있다.
- /etc/services 에서 포트와 매핑을 볼 수 있으며, 확시하지 않은 경우 전체 TCP와 UDP 포트 번호 목록을 참조하면 된다.
- 로컬 시스템에서 사용 중인 항목을 보려면 다음을 확인해보자(다른 사람의 컴퓨터나 로컬이 아닌 IP에서 시도해서는 안된다.)
1
nmap -A localhost
전송 제어 프로토콜(TCP)
- TCP는 HTTP와 SSH를 포함한 여러 고수준 프로토콜에서 사용되는 연결 지향 전송 계층 프로토콜이다.
- 이는 패킷을 순서대로 전달하는 것을 보장하고 오류 발생 시 재전송을 지원하는 세션 기반 프로토콜이다.
- TCP는 연결 수립부터 종료까지 연결 상태를 추적하며 송신자와 수신자 모두와 전송할 데이터의 양(TCP 윈도 크기)부터 QoS까지 특정 항목들을 협상해야 한다.
- 보안 관점에서 보면 TCP에는 방어 메커니즘이 없다.
- 즉 페이로드는 일반 텍스트로 전송되며 발신자와 수신자 사이의 누구나 패킷을 검사할 수 있다.
- 메시지 암호화를 활성화하려면 TLS 프로토콜을 사용해야 하며, 그중에서도 RFC 8446을 따르는 1.3 버전이 가장 이상적이다.
사용자 데이터그램 프로토콜(UDP)
- UDP는 통신 설정 없이 데이터그램이라고 부르는 메시지를 보낼 수 있는 비연결형 전송 계층 프로토콜이다.
- 그럼에도 무결성을 보장하기 위해 데이터그램 체크섬을 지원한다.
- NTP, DHCP와 DNS처럼 UDP를 사용하는 애플리케이션 수준 프로토콜은 많다.
소켓
- 리눅스에서 제공하는 고수준의 통신 인터페이스가 바로 소켓이다.
- 소켓은 TCP나 UDP포트와 IP 주소로 구성된 튜플이라는 고유한 ID를 가진 통신의 엔드포인트라고 생각하자.
- 소켓은 네트워크 관련 도구나 앱을 개발하는 경우에만 사용할 가능성이 높긴 하지만, 최소한 쿼리하는 방법은 알고 있는 편이 좋다.
- 예를 들어 도커 데몬의 경우, 적어도 소켓에 필요한 권한 정도는 알야아 한다.
ss
명령을 사용해 소켓 관련 정보를 표시하는 방법을 알아보자. ```bash ss -s # 시스템에서 사용 중인 TCP 소켓에 대한 개요를 알고 싶다고 가정 했을 때
ss -ulp # 엔드포인트 IP 주소같이 좀 더 세부적인 정보와 함께 UDP 정보를 얻을 수 있다.
1
2
3
4
5
- 소켓과 프로세스 관련해 유용하게 사용할 수 있는 또 다른 도구로는 `lsof`가 있다.
- 예를 들어 내 컴퓨터에서 크롬이 사용하는 UDP 소켓을 살펴볼 수 있다.
```bash
lsof -c chrome -i udp
DNS
- IP 주소는 기억하기 어렵고 바뀔 수 있지만 이름은 동일하게 유지된다.
- 때문에 /etc/hosts를 이용해 이름과 IP 주소 간의 매핑을 로컬로(단일 시스템의 경우) 유지하는 것이다.
- 네트워크 정보 센터(NIC)는 FTP를 톹해 HOSTS.TXT라는 파일을 모든 참여 호스트와 공유한다.
- 이와 같은 중앙 집중식 접근 방식으로는 성장하는 인터넷을 따라갈 수 없다는 사실이 금세 드러났다.
- 그에 따라 분산 시스템으로 설계됐다.
- DNS란 인터넷의 호스트와 서비스 모두를 위해 전 세계에서 사용하는 계층적인 명명 시스템이다.
주요 개념
도메인 네임 스페이스
- .(마침표)가 루트인 트리 구조로, 각 트리 노드와 리프에는 특정 공간에 대한 정보가 포함돼 있다.
- 리프에서 루트까지의 경로인 레이블을 정규화된 도메인 네임(FQDN)이라고 한다.(최대 길이 63 바이트)
- 도메인 네임 스페이스의 노드나 리프에 있는 페이로드
네임 서버
- 도메인 트리 구조에 대한 정보를 가지고 있는 서버 프로그램.
- 네임 서버가 네임 스페이스에 대한 완전한 정보를 가지고 있는 경우 권위(authoritative) 있는 네임 서버라고 한다.
- 권위 있는 정보는 존으로 구성된다.
리졸버(resolver)
- 클라이언트 요청에 대한 응답으로 네임 서버에서 정보를 추출하는 프로그램.
- 이들은 로컬에 있는 시스템이며, 리졸버와 클라이언트 간의 상호 작용을 위해 정의된 명시적인 프로토콜은 없다.
- 대다수 시스템은 DNS 질의를 처리하기 위한 라이브러리 호출을 지원한다.