본문 바로가기
IT

리눅스에서 NetEm(Network Emulator)를 사용하여 Traffic Control(패킷 지연,유실,대역폭 제한등)하고 테스트 하는 방법

by geddy 2024. 1. 25.

NetEm은 "Network Emulator"의 약자로, Linux 트래픽 제어 기능을 확장하여 선택한 네트워크 인터페이스에서 나가는 패킷에 대해 지연, 패킷 손실, 중복 등의 특성을 추가할 수 있게 해주는 도구입니다. 이 도구를 이용해서 다양한 네트워크 지연 상황에 대한 시뮬레이션과 테스트를 해 볼 수 있는 유용한 도구입니다. 오늘은 이 NetEm을 사용하는 방법을 알아보도록 하겠습니다.

리눅스에서 NetEm(Network Emulator)를 사용하여 Traffic Control(패킷 지연,유실,대역폭 제한등)하고 테스트 하는 방법 썸네일

NetEm 이란?

NetEm은 Linux 트래픽 제어 기능을 확장하여 선택한 네트워크 인터페이스에서 나가는 패킷에 대해 지연, 패킷 손실, 중복 등의 특성을 추가할 수 있게 해주는 도구입니다. NetEm은 Linux 커널의 기존 Quality Of Service (QOS) 및 Differentiated Services (diffserv) 기능을 사용하여 구축되었습니다.

NetEm은 Linux 커널 버전 2.6.12부터 지원됩니다.

NetEm은 네트워크 프로토콜을 테스트하기 위해 넓은 영역 네트워크의 속성을 에뮬레이션하는 기능을 제공합니다². 이를 통해 실제 네트워크와 같은 네트워크 장애 조건을 테스트할 수 있습니다.

NetEm의 주요 옵션은 다음과 같습니다.

  • limit packets: 선택한 옵션의 효과를 지정된 수의 다음 패킷으로 제한합니다.
  • delay: 선택한 네트워크 인터페이스로 나가는 패킷에 지연을 추가합니다.
  • drop:

NetEm을 사용하면 네트워크 조건을 설정하고, 확인하고, 네트워크 손상을 중지하는 등의 작업을 수행할 수 있습니다.

NetEm은 네트워크 프로토콜을 테스트하고 분석하기 위한 완벽한 도구로, 다음과 같은 네트워크 시뮬레이션 항목을 제공합니다:

1. 지연(Delay): 패킷에 지연을 추가하여 네트워크의 전송 속도를 조절합니다.
2. 지터(Jitter): 패킷 전송 간의 변동성을 추가합니다.
3. 패킷 손실(Packet Loss): 일부 패킷이 전송 중에 손실되는 상황을 시뮬레이션합니다.
4. 패킷 중복(Packet Duplication): 일부 패킷이 전송 중에 중복되는 상황을 시뮬레이션합니다.
5. 패킷 재정렬(Packet Reordering): 패킷의 순서가 변경되는 상황을 시뮬레이션합니다.

지연 vs 지터

지연(Delay)은 네트워크의 한 지점에서 다른 지점으로 데이터가 이동하는 데 걸리는 시간을 의미합니다. 이는 여러 요인에 의해 복잡하게 영향을 받습니다.

반면에 지터(Jitter)는 두 패킷 간의 지연 시간의 차이를 의미합니다. 이 또한 네트워크 상의 여러 요인에 의해 발생할 수 있습니다.

더 구체적으로 말하면, 지연은 신호가 송신자로부터 수신자까지 도달하는 데 필요한 종단 간 시간을 정의하며, 지터는 동일한 흐름에 속하는 패킷의 지연에 대한 변동을 정의합니다.

tc 명령을 통한 NetEm테스트 방법

tc는 "Traffic Control"의 약자로, Linux 커널에서 네트워크 트래픽을 제어하는 데 사용되는 명령어입니다.
리눅스에서 NetEm을 사용하는 것은 tc 명령을 통해서 실행됩니다.
tc를 통한 패킷 지연과 네트워크 테스트를 하는 방법은 다음과 같습니다.

NetEm 모듈 활성화 확인

먼저, NetEm 커널 모듈이 사용 가능한지 다음 명령을 통해 확인해야 합니다.

modinfo sch_netem

 

저의 경우 다음과 같이 출력되어 사용할 수 있는 것으로 나타납니다.

:~$ modinfo sch_netem
filename:       /lib/modules/6.5.0-14-generic/kernel/net/sched/sch_netem.ko
license:        GPL
srcversion:     1A42F6792716B98242CDFE4
depends:
retpoline:      Y
intree:         Y
name:           sch_netem
vermagic:       6.5.0-14-generic SMP preempt mod_unload modversions
sig_id:         PKCS#7
signer:         Build time autogenerated kernel key
sig_key:        27:7D:EE:09:F3:EE:9A:D7:DC:7C:70:59:47:5E:43:79:D3:62:E0:D4
sig_hashalgo:   sha512
signature:      49:5C:20:47:9E:BF:4D:03:2E:0A:09:DD:E4:45:A4:16:D4:ED:E8:7E:
                50:CA:A3:4A:97:F1:55:AD:8A:11:36:79:89:FD:CB:7B:96:6A:94:1D:
                0B:90:FE:6F:B5:D8:AB:C8:A5:7D:AA:62:11:8D:D2:88:B8:73:4B:24:
                F4:B3:FF:48:9C:70:95:CC:10:E4:21:F6:5B:D0:8A:03:4F:21:65:8F:
                1C:3E:5D:14:6D:58:C6:42:2B:A2:67:F1:1F:6F:94:FC:FA:22:8F:F1:
                CC:B4:5C:D5:AC:4E:80:40:69:EF:2B:63:E3:F3:EE:05:83:89:DF:72:
                67:06:85:96:38:01:F0:CF:7B:D6:FF:FA:FE:C7:3A:89:14:7D:A7:55:
                42:87:EC:B3:49:E9:5C:85:1B:E1:7C:31:05:B7:B8:4E:C6:6B:E0:B7:
                51:1A:F1:20:C4:64:76:7F:50:02:71:C7:1F:92:1E:91:AF:12:FA:15:
                44:41:D9:00:B2:8D:7B:60:E3:37:AE:17:5C:4B:08:E1:DF:EE:EE:1A:
                C9:57:E7:36:37:D6:94:0A:88:54:C3:90:68:27:07:34:53:23:06:12:
                87:8D:EA:93:1B:9B:17:7C:ED:7D:FF:3B:94:70:AF:46:80:9E:EA:84:
                0E:19:44:FA:2D:45:50:70:30:A3:AA:0D:2D:BF:58:AA:9D:6E:E2:AB:
                C7:7A:68:74:4C:F3:3E:71:AC:C3:E4:30:70:3A:1E:17:E5:5B:98:AD:
                21:74:02:DB:31:A0:A1:B2:54:2A:4D:2F:C6:69:FC:C8:9B:68:53:6B:
                6B:C6:EB:B4:AC:0A:EA:80:28:0A:EC:2C:39:F3:EC:A1:D7:B1:7D:51:
                22:73:2B:86:22:C7:96:82:15:6D:CF:41:97:51:E5:10:10:EC:5E:6A:
                66:8E:00:06:6F:81:12:94:A1:0F:84:17:AC:15:3B:E1:39:FC:13:A8:
                C0:41:B7:2A:3C:79:A6:AE:68:06:58:43:B2:BB:75:D6:AD:20:D2:21:
                25:0A:AB:CA:23:18:23:04:AA:EF:8E:50:B7:39:48:70:47:07:B8:CB:
                B1:41:D9:65:3A:EE:3D:5F:CB:A9:79:E7:85:0D:CF:FC:35:82:AC:40:
                8D:47:AB:C7:50:9D:AF:AC:11:F8:1A:8E:27:E9:AF:91:33:E5:3F:91:
                FD:CD:41:4E:DE:CE:AD:CE:D9:A1:CD:CA:4C:5A:0B:90:5B:17:A9:4C:
                27:72:C6:34:BB:39:69:35:D4:3B:54:00:AF:99:06:2A:90:A4:7E:24:
                6A:03:83:5A:7D:71:C4:F4:FA:D7:12:28:B7:4A:D5:C5:D1:1C:44:DD:
                A3:A2:F8:A1:54:97:03:9E:8F:1D:7A:2F

 

eth1 장치에 지연 명령 추가

네트워크 시뮬레이션을 위해 `tc` 명령어를 사용할 수 있습니다. 예를 들어, `eth1`이라는 장치에 대해 100ms의 지연을 추가하려면 다음과 같은 명령을 통해서 네트워크 지연을 시뮬레이션 할 수 있습니다.

 

1. 명령수행

tc qdisc add dev eth1 root netem delay 100ms

 

Linux의 tc (Traffic Control) 도구를 사용하여 특정 네트워크 인터페이스에 대한 패킷 지연을 설정하는 위 명령에 대해서 각 부분은 다음과 같이 설명할 수 있습니다.

  • tc: Traffic Control의 약자로, Linux에서 네트워크 트래픽을 제어하는 데 사용되는 명령어입니다.
  • qdisc: Queueing Discipline의 약자로, 패킷을 받고 서비스하기 위한 룰들의 집합이라고 보면 됩니다. 쉽게 다시 이야기 하면 패킷이 어떻게 처리되는지를 결정하는 규칙을 나타냅니다.
  • add: 새로운 규칙을 추가하라는 명령어입니다.
  • dev eth1: eth1이라는 장치에 대해 작업을 수행하라는 명령어입니다.
  • root: 이 규칙이 해당 장치의 루트(가장 상위) 레벨에 적용되어야 함을 나타냅니다.
  • netem: Network Emulator의 약자로, 네트워크 조건(예: 지연, 손실 등)을 에뮬레이션하는 데 사용되는 도구입니다.
  • delay 100ms: 패킷에 100 밀리초의 지연을 추가하라는 명령어입니다.

 

저는 테스트를 위해서 lo( localhost 장치에 테스트 해보겠습니다. )
tc qdisc add dev lo root netem delay 100ms 명령을 수행하면 아래와 같이 권한에러가 납니다. 네트워크 장치에 지연명령을 추가하는 것으로 sudo 권한이 필요합니다.

~$ tc qdisc add dev lo root netem delay 100ms
RTNETLINK answers: Operation not permitted
~$ sudo tc qdisc add dev lo root netem delay 100ms
[sudo] password for eddy:

 

2. 지연 확인

이제 `tc qdisc show dev eth1` 명령어를 사용하여 NetEm이 설정되었는지 확인할 수 있습니다. 이 명령어를 실행하면 NetEm이 설정된 것을 확인할 수 있습니다.

#tc qdisc show dev eth1 (eth1의 결과를 보려면 dev에 eth1을 넣어 줍니다)
#예제는 lo(localhost)결과 보기
~$ tc qdisc show dev lo
qdisc netem 8001: root refcnt 2 limit 1000 delay 100ms

3. 패킷 지연 테스트

패킷이 실제로 지연되는지 테스트하기 위한 가장 간단한 방법으로 ping을 사용하실 수 있습니다.

아무것도 하지 않은 lo(localhost) 장치의 ping 시간은 0.056 정도에서 왔다갔다합니다.

~$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.056 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.056 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.057 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=0.058 ms
64 bytes from 127.0.0.1: icmp_seq=4 ttl=64 time=0.058 ms
^C--- localhost ping statistics ---
5 packets transmitted, 5 packets received, 0% packet loss
round-trip min/avg/max/stddev = 0.056/0.057/0.058/0.000 ms

 

하지만, delay 100ms를 주고 난 후 ping을 테스트 하면 왕복으로 추가되어 200ms 정도가 추가됩니다.

~$ ping localhost
PING localhost (127.0.0.1): 56 data bytes
64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=200.306 ms
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=200.273 ms
64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=200.257 ms
64 bytes from 127.0.0.1: icmp_seq=3 ttl=64 time=200.256 ms
^C--- localhost ping statistics ---
5 packets transmitted, 4 packets received, 20% packet loss
round-trip min/avg/max/stddev = 200.256/200.273/200.306/0.000 ms

 

이 외에도 `netperf`라는 도구를 사용하여 패킷 지연을 테스트할 수 있습니다. 하지만, netperf는 리눅스에서 기본으로 제공되지는 않아서 테스트를 위해서는 설치를 해 주어야 합니다. 사용법은 아래와 같습니다.
netperf -H $my_ip -t TCP_RR -P 0 -- -r 64 -o RT_LATENCY

위의 명령어는 `$my_interface` 장치에 100ms의 지연을 추가하고, `netperf` 도구를 사용하여 지연을 테스트합니다.

4. 패킷 지연 제거

테스트가 끝나면 `tc qdisc del dev eth1 root` 명령어를 사용하여 지연을 제거할 수 있습니다. 저의 경우 lo로 테스트하여 해당 dev의 지연 규칙을 제거하였습니다.

~$ sudo tc qdisc del dev lo root
~$ tc qdisc show dev lo
qdisc noqueue 0: root refcnt 2


이러한 방법을 통해 리눅스에서 NetEm을 사용하여 패킷 지연과 네트워크 테스트를 수행할 수 있습니다.

기타 시뮬레이션

netem은 앞서 설명드린것 처럼 패킷 지연 뿐 아니라 손실이나 중복 등도 테스트 가능합니다.

패킷 손실률

NetEm을 사용하여 패킷 손실률을 설정하는 방법은 다음과 같습니다.

sudo tc qdisc add dev eth1 root netem loss 1%

위의 명령어는 `eth1` 장치에서 나가는 패킷의 1%를 무작위로 손실하도록 설정합니다. 이 명령어를 사용하면 네트워크의 패킷 손실률을 시뮬레이션할 수 있습니다.

또한, 패킷 손실률과 성공률을 함께 설정할 수도 있습니다. 예를 들어, 다음 명령어는 패킷의 1%를 무작위로 손실하고, 그 중 30%는 성공적으로 전송되도록 설정합니다.
sudo tc qdisc add dev eth1 root netem loss 1% 30%

NetEm을 사용하여 각각의 네트워크 시뮬레이션 항목을 테스트하는 방법은 다음과 같습니다.

지터(Jitter)

패킷 전송 간의 변동성을 추가하려면, `delay` 옵션에 두 번째 인수로 지터 값을 추가할 수 있습니다. 예를 들어, 평균 지연 시간이 100ms이고 지터가 10ms인 경우, 다음과 같이 명령어를 작성할 수 있습니다.

sudo tc qdisc add dev eth1 root netem delay 100ms 10ms

패킷 중복(Packet Duplication)

일부 패킷이 전송 중에 중복되는 상황을 시뮬레이션하려면, `duplicate` 옵션을 사용하면 됩니다. 예를 들어, 패킷 중복률을 1%로 설정하려면 다음과 같이 명령어를 작성할 수 있습니다.

sudo tc qdisc add dev eth1 root netem duplicate 1%

패킷 재정렬(Packet Reordering)

패킷의 순서가 변경되는 상황을 시뮬레이션하려면, `reorder` 옵션을 사용하면 됩니다. 예를 들어, 패킷 재정렬률을 25%로 설정하려면 다음과 같이 명령어를 작성할 수 있습니다.

sudo tc qdisc add dev eth1 root netem reorder 25%

 

패킷 깨뜨리기(Packet Corrupt)

패킷을 깨뜨리는 것은 다음과 같이 corrupt 명령을 통해 비율로 설정할 수 있습니다. 

tc qdisc change dev eth0 root netem corrupt 0.1%

결론

오늘은 리눅스 환경에서 netem이 무엇이고 어떻게 사용해서 패킷 손실이나 지연을 시뮬레이션 할 수 있는지를 알아보았습니다. 소프트웨어 테스트나 개발시에 네트워크 문제 환경에서도 잘 동작하는지 확인해보기 위해서는 netem을 이용해서 아주 쉽게 네트워크 비정상 상황에 대한 테스트를 할 수 있습니다.

facebook twitter kakaoTalk kakaostory naver band shareLink