네트워크 구조

계층 관점 요약

  • Thanks for ChatGPT
[ User Space ]
 ├─ Application (curl, ssh, nginx)
 │    └─ socket(), send(), recv()
 └───────────────────────────────
[ Kernel Space ]
 ├─ Socket Layer
 ├─ Transport Layer (TCP / UDP)
 ├─ Network Layer (IP / Routing)
 ├─ Netfilter (iptables / nftables)
 ├─ Qdisc / TC (Traffic Control)
 ├─ Device Layer
 └─ NIC Driver

[ Network Interface ]

Socket Layer

  • 유저 공간이랑 커널 공간의 경계에 있음
  • 소켓 : 프로토콜, IP 주소, 포트로 구성됨. 양쪽 호스트의 데이터 송수신 통로
  • 파일 디스크립터로 추상화 함
  • 여기서 TCP, UDP에 따라 분기가 됨
    • TCP로 설정한 경우 Transport Layer로 내려감
    • UDP로 설정한 경우 Transport Layer를 건너뛰고 Network Layer로 바로 감

Transport Layer

  • TCP 내부 동작
    • 연결 상태 관리
    • 재전송
    • 흐름 제어
    • 혼잡 제어
  • UDP는 관계 없음. TCP가 하는 동작들 안함

Network Layer

  • 목적지 IP 확인
  • 라우팅 테이블 조회
  • 필요하면 Fragmentation
  • 아래 명령어 쓰면 네트워크 레이어 단 까지의 결과를 보여줌
ip route get <목적지_IP>
  • 예시
ip route get 8.8.8.8

라우팅 결정 순서

  1. Routing Policy DataBase 작동 (Routing Rule을 보고 봐야하는 Routing Table 선정)
  2. FIB 작동 (Longest Prefix Match, Metric 비교)
  3. 해시 기반 next-hop 선택
  4. 출력 인터페이스 결정

Routing Policy DataBase

Routing Rule
  • “해당 조건에 맞는 패킷들은 이 테이블을 확인하시오” 라는 내용을 정리한 것
  • 아래 명령어로 확인 가능
ip rule show

  • 우선순위 / from 특정 위치 / lookup 테이블명

    • 우선순위 : 숫자가 낮을 수록 우선순위 높음
    • from 특정 위치 : 특정 위치에서 오는 패킷은…
    • lookup 테이블명 : 테이블명 < 테이블을 확인하시길!
  • 예시

200 : from 192.168.0.152 lookup test
# 우선순위 : 200
# 192.168.0.152 에서 오는 패킷은 test 라는 테이블을 확인하시길!
Routing Table (= FIB)
  • 아래 명령어로 확인 가능
ip route show table <테이블>
 
# 예시
ip route show table main
  • 출력
<목적지_주소> via <다음_홉_게이트웨이> dev <출력_인터페이스> proto <라우트_생성_주체> scope <유효_범위> src <송신_시_사용할_IP> metric <비용> weight <비율>
  • 출력 예시
192.168.1.0/24 dev eth0 proto kernel scope link src 192.168.1.10
  • 위 예시의 경우에는 유효 범위가 같은 링크기 때문에, 다음 홉에 게이트웨이로 빠질 이유가 없음. 따라서 via 필드를 사용하지 않았음.

  • 위 예시 해석

    • 목적지가 192.168.1.0 ~ 192.168.1.255 인 패킷에 대해 작동
    • 사용하는 통신 인터페이스는 eth0
    • 라우트 송신 주체는 커널
    • 범위는 링크 (같은 네트워크 내)
    • 프로세스가 송신 IP를 명시하지 않는 경우, 송신 IP는 192.168.1.10
  • 참고 : metric 뒤에 붙는 비용의 경우 longest prefix match의 우선순위가 동일하다는 가정 하에 작동함.

  • 참고 2 : weight 뒤에 붙는 가중치의 경우 ECMP에서 사용됨. 그러나 절대적인 트래픽 비율을 의미하진 않음

FIB

  • Forwarding Information Base
  • 커널 내부에 있고 데이터를 보낼 때 여기를 거쳐서 보고 보냄 (== Routing Table)
  • 패킷을 보내야 할 때 Routing Table 에서 LPM Metric 비교 ECMP 확인 순으로 진행함
    • LPM : Longest Prefix Match. 목적지 주소에 맞는 조건을 찾을 때, 가장 주소를 “자세히” 표현한 목적지 범위를 찾음
    • Metric : LPM으로 찾은 조건이 두 개 이상일 때, Metric(비용)이 낮은 조건을 우선적으로 찾음
    • ECMP : Equal-Cost Multi-Path. LPM도 동일, Metric도 동일할 때 작동함.
      • 5-tuple(출발/도착지 IP/port, L4 프로토콜) 가지고 해시값을 계산해서 그걸로 경로를 고름

NetFilter

  • 커널 내부에 있는 패킷 처리 프레임워크
  • 후킹 포인트를 커널 네트워크 스택(처리 순서)에 심어넣음
    • 후킹 : 패킷을 가로채는 것
    • 후킹 포인트 : 패킷을 가로채는 구간
  • 알아야 하는 주요 개념은 Rule, Chain, Table

  • 이미지 출처

  • 패킷 출발/도착지에 따른 후킹 포인트 작동 순서

패킷 유형Hook 순서
외부 → 로컬PREROUTING → INPUT
외부 → 외부 (포워딩)PREROUTING → FORWARD → POSTROUTING
로컬 → 외부OUTPUT → POSTROUTING

Rule

  • 패킷을 어떻게 제어할지에 대한 구체적인 규칙
  • 각 테이블에 등록되는 체인은 최소 하나 이상의 룰을 가지고 있다 (따로 지정 안한다면 알아서 default policy 적용함)

Matching

  • 적용 조건

Target

  • 적용 조건 (Matching)에 부합하는 패킷을 어떻게 처리할 것인가에 대한 것
  • 크게 terminating과 non-terminating이 있음
  • non-terminating action을 수행하다가 terminating packet을 만나면 그 아래로는 수행하지 않고 다음 체인으로 넘어감

Chain

  • 후킹 포인트과 1:1 대응되는 패킷 제어 룰 그룹
  • 특정 후킹 포인트에서 훅이 실행될 때 그에 대응되는 체인에 등록된 룰이 실행됨

Table

  • 총 5개의 테이블 존재
  • Filter, NAT, Mangle, Raw, Security
  • 테이블에 체인을 등록해서 특정 체인에서 테이블을 작동시키게끔 할 수 있음

Filter Table

  • 패킷을 허용/거부하는데 쓰임

NAT Table

  • 목적지 (DNAT) 혹은 출발지 (SNAT) 를 변경하는데 쓰임

Mangle Table

Raw Table

  • 연결 상태를 제어, 마킹하는데 쓰임
  • 사용자가 직접 Raw Table을 제어하는 일은 많지 않음

Security Table

  • security context에 마킹하는데 쓰임

Qdisc / TC

  • NIC 로 패킷이 가기 직전에, 커널이 패킷을 정렬/제어하는 계층
  • 라우팅 결정 후 물리적 전송 이전의 마지막 단계
  • QoS의 커널 구현체

QoS?

  • Quality of Service, 서비스 품질

  • 특정 데이터의 속도나 품질을 보장하거나 우선순위를 결정하는 기술

  • QoS에서 제어하는 것들

    • 대역폭 : 중요한 서비스에 더 많은 대역폭을 배정
    • 우선순위 :중요한 트래픽을 먼저 처리
    • 지연 및 지터(신호의 불안정성) 최소화
    • 패킷 손실 방지
  • 자료 출처

Qdisc 가 하는 일

1. 패킷 스케줄링

  • NIC는 한 번에 한 패킷만 전송이 가능함
  • 여러 프로세스 혹은 소켓에서 패킷이 몰리면, 뭘 먼저 보낼지를 정해야 함
  • Qdisc가 결정하는 것
    • 어떤 패킷을 먼저 보낼지
    • 특정 트래픽을 우선 처리할지
    • 특정 흐름이 독점하지 못하도록 할지

2. 대역폭 제한

  • 의도적으로 전송 속도를 낮출 수 있음
  • 왜 윗단 (어플리케이션 레이어)에서 안하고 여기서 함?
    • 부정확할 수 있어서
  • 왜 NIC가 안함?
    • NIC는 너무 빨리 그냥 보내버림

3. 지연 / 드랍 시뮬레이션 (Queue Management)

TX/RX 큐

  • TransmitQueue / Receive Queue
  • 패킷을 보내기/받기 전에 임시로 저장해두는 큐

BufferBloat

  • 시간이 지나면서 장비들의 성능이 점점 올라가고 있음

  • 이는 네트워크 장비도 마찬가지

  • 그러다보니 NIC 가 패킷을 보내기 전에 모아두는 버퍼 TX 가 커졌음

  • 문제는… TX가 커지다보니 패킷 지연시간이 엄청나게 늘어나는거임

  • 게다가 TCP는 패킷이 손실되지 않으면 문제가 없다고 봄…

  • 그래서 그 상황에 대한 개선을 안하려고 함

  • 그게 BufferBloat 현상

  • 현실 예시

    • 점심시간에 밥집에 가려고 함
    • 너무 맛있는 밥집인데 점심에는 신선도 유지때매 50팀만 받는다고 함
    • 그러면 적당히 줄 선거 보고 50팀 넘으면 마감되었다고 함
    • 그 밥집에 가려던 사람들은 마감된거 보고 포기하고 다음 날에 가던가 할거임
    • 근데 50팀만 받는게 아니고 500팀을 받는다고 가정 (버퍼 증가)
      • 사람들은 한 번 줄을 섰으면 이탈하지 않을 것이라고 가정 (+ 패킷 드랍 X)
    • 집밥 사장님은 어쨌든간에 밥을 제공했기 때문에 문제가 없다고 말함 (+ TCP)
    • 그러면 500번째 팀은 점심시간 끝나고 나서도 밥을 못먹을거임 (= 지연시간 폭증)

AQM (Active Queue Management)

  • 위에서 말한 BufferBloat 현상을 해결하려고 나온게 AQM
  • 지연시간이 너무 길어지는 경우에는 패킷을 일부러 드랍시킴
  • 패킷이 드랍됨 TCP가 보기에는 패킷 손실 큐 감소 전송 속도 감소
  • 좀… 그만 보내라는 티를 내는 것

PQM (Passive Queue Management)

  • 큐가 꽉 차면 그때야 발동하는 것
  • 혼잡을 미리 감지하질 않음
  • 지연 기준이 아니고 큐 용량 기준임

Device Layer

  • 커널이 관리하는 논리적 네트워크 인터페이스 계층
    • 네트워크 장치를 추상화된 객체(struct net_device) 로 관리
    • 상위 계층(IP, Qdisc)은 하드웨어 종류를 몰라도 통신 가능
    • 하나의 물리 NIC ↔ 여러 논리 인터페이스 가능
  • Device Layer에서 관리하는 것
항목설명
인터페이스 상태UP / DOWN
MTU패킷 최대 크기
MAC 주소L2 주소
TX/RX 큐qdisc와 연결
통계 카운터RX/TX bytes, packets
상위 계층 연결IP, TC, Netfilter
  • ip link 명령어로 보이는 부분이 이 계층에 대한 정보값
  • UP : 논리 인터페이스 활성화 됨

  • LOWER_UP : 실제 물리 연결 활성화 됨

  • BROADCAST : 브로드캐스트 주소로 송신 가능

  • MULTICAST : 멀티캐스트 송수신 가능

  • NO-CARRIER : 실제 물리 연결 활성화 안됨

  • PROMISC : 무차별 모드. 모든 프레임 수신 (보통 패킷 캡쳐/브릿지)

  • 플래그 조합 예시

출력해석
<UP,LOWER_UP>정상
<UP,NO-CARRIER>물리 링크 문제
<BROADCAST,MULTICAST,UP>케이블 미연결이지만 논리적으론 다 가능
<PROMISC,UP,LOWER_UP>패킷 캡처/브리지

NIC Driver

  • 실제 NIC 를 제어하는 드라이버
  • Device Layer에서 호출하는 함수의 구현체가 포함됨

NIC Driver가 하는 일

1. DMA (Direct Memory Access)

  • NIC가 CPU 개입 없이 메모리로 패킷 송수신
  • RX/TX Ring Buffer 사용

2. 인터럽트 처리

  • 패킷 수신/전송 완료 시 NIC가 CPU에 알림
  • 문제는 고속 네트워킹의 경우 패킷 송수신이 매우 빠르고 잦게 일어남
  • 따라서 이 CPU한테 인터럽트가 무리하게 가는 것(Interrupt Storm)을 방지해야 함
  • 해결 방식:
    • NAPI (New API)
      → 인터럽트 + 폴링 혼합 방식

3. netdev_ops 구현

  • netdev_ops : Device Layer와 NIC Driver를 연결하는 함수 테이블

  • 몇 가지 예시

함수의미
ndo_open인터페이스 up
ndo_stopdown
ndo_start_xmit패킷 전송
ndo_set_rx_mode멀티캐스트 설정

다음에 할 것

  • 이번 시간에 배운 내용을 토대로 명령어를 사용해 네트워킹 관련 설정을 확인하고 수정해보기