LoginSignup
1
1

More than 1 year has passed since last update.

Amazon Linux2でネットワーク帯域制御と遅延追加をやってみた

Posted at

目的

ネットワーク上で制約のある環境を疑似的に再現し、通信の挙動を確認したい。

  • 通信帯域の上限を設定する
  • 通信の遅延を設定する

やってみた方法

  • AmazonLinux2でip forwardを有効にし、ルーターとして利用。
  • 通信帯域の上限設定
    • iptablesのlimit(hashlimit)
    • iprouteのtcコマンド
  • 通信の遅延
    • iprouteのtcコマンド

ネットワーク構成

bandwidth_diagram.drawio.png

 EC2(A)---EC2(NAT)(ルーター用)---EC2(B)

  • VPCを作成
  • サブネットを2つ作成
  • EC2(A), EC2(B)をそれぞれのサブネットへ配置
  • EC2(NAT)をEC2(A)と同じサブネットで作成。
  • EC2(NAT)にENIを追加し、(B)と同じサブネットへ接続
  • 各サブネット向けのルートテーブルを作成、相互にルートを追加しておく
  • EC2(NAT)のネットワーク設定で「ソース/宛先チェック」を停止しておく
  • セキュリティグループは必要なものを空けておく
  • EC2(NAT)の基本設定
#IP Forwadingを有効にしておく
sudo sh -c "echo 1 > /proc/sys/net/ipv4/ip_forward"
sudo sh -c "echo net.ipv4.ip_forward=1 >> /etc/sysctl.conf"

#iptablesをインストール・サービスを有効化
sudo yum -y install iptables-services
sudo yum iptables -F
sudo systemctl start iptables
sudo systemctl enable iptables

#tcコマンドを利用するためiproute-tcをインストール
sudo yum -y install iproute-tc

#通信状況を確認するため、dstatをインストール
sudo yum -y install dstat

通信帯域の上限設定1 (最初に検索で見つけた方法)

iptablesのhashlimitを利用。(SCPでの転送確認をやりつつ、EC2(B)にSSHアクセスも行いたかったため、ソースIP単位で制御されるhashlimitを利用。)

limit / limit-burstの考え方の解説は以下参照
https://atmarkit.itmedia.co.jp/ait/articles/1007/14/news102.html

sudo iptables -I FORWARD -p tcp -m tcp --dport <ポート番号> -j REJECT
sudo iptables -I FORWARD -p tcp -m tcp --dport <ポート番号> -m hashlimit --hashlimit-name <設定の名称> --hashlimit <単位あたりのパケット数>/s --hashlimit-burst <バーストするまでの上限> -j ACCEPT
sudo service iptables save

先にREJECTを設定しているのは、hashlimitを超えたときに、この行の条件に合致してREJECTされるようにしているらしい。(本来はDoS攻撃の対策機能の模様。)

(例)

sudo iptables -I FORWARD -p tcp -m tcp --dport 22 -j REJECT
sudo iptables -I FORWARD -p tcp -m tcp --dport 22 -m hashlimit --hashlimit-name sshscplimit --hashlimit 100/s --hashlimit-burst 1 -j ACCEPT

( 100 packet/sec × 1500byte(MTU) = 150,000byte/sec = 約150Kbps )

設定状況確認

$ sudo iptables -L -n
Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination
ACCEPT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 limit: up to 100/sec burst 1
REJECT     tcp  --  0.0.0.0/0            0.0.0.0/0            tcp dpt:22 reject-with icmp-port-unreachable

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

SCPでEC2(A)からEC2(B)へ100MByteのファイルをコピー。EC2(NAT)にて「dstat 1」で帯域を確認。
recvは150kbps前後ですが、sendは60-80kbpsになっていました。受け側での制御なので、こんなものなのでしょうか・・・。
スクリーンショット 2022-11-08 231733.png

tcによる制御

参考にさせていただいたページ
https://qiita.com/shirok/items/f57e0ecd86abec33a087
https://pig-log.com/tcp-segmentation-offload/

通信帯域の上限設定2

EC2(NAT)のeth1へ設定。(EC2(A)⇒EC2(B)方向へ転送するため、EC2(NAT)の出口側へ設定)

#1Mbpsに上限を設定
#※再起動しても消えないようにするためには、起動スクリプトへの組み込みが必要。
sudo tc qdisc add dev eth1 root tbf limit 1Mb buffer 200Kb rate 1Mbps
sudo ethtool -K eth1 gso off

gso off はセグメンテーションのオフロードをオフにしている。
ネットワークアダプタで処理しないようにするため(・・・と理解している。)

# 設定前のデフォルト状況確認
$ sudo ethtool -k eth1 | grep segmentation-offload
tcp-segmentation-offload: off
generic-segmentation-offload: on
# gsoのみonであったため、offに変更
$ sudo ethtool -K eth1 gso off
# 設定後の状況確認
$ sudo ethtool -k eth1 | grep segmentation-offload
tcp-segmentation-offload: off
generic-segmentation-offload: off

スクリーンショット 2022-11-08 233656.png

通信の遅延追加

帯域制御と遅延追加は、どうやら排他的になっているようなので、遅延はEC2(NAT)のeth0に設定。

設定の追加
$ sudo tc qdisc add dev eth0 root netem delay <遅延時間>

設定の変更
$ sudo tc qdisc change dev eth0 root netem delay <遅延時間>

設定状況の確認
$ sudo tc qdisc show dev eth0
qdisc netem 8001: root refcnt 3 limit 1000 delay <遅延時間>

(例)

$ sudo tc qdisc add dev eth0 root netem delay 200ms
$ sudo tc qdisc change dev eth0 root netem delay 500ms
$ sudo tc qdisc show dev eth0
qdisc netem 8001: root refcnt 3 limit 1000 delay 500ms
1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1