Macで自由にパケットのフィルタリング、帯域制限、パケロス率の設定をする
Macにおいて、ネットワーク帯域の制御などはNetwork Link Conditionerで対応可能です。
下記ページよりAdditional Tools for Xcode を探してdmgをダウンロードし、その中にあるNetwork Link Conditioner.prePane からインストール可能です。
https://developer.apple.com/download/all/
そうすると、システム環境設定の中にNetwork Link Conditionerがあるので、そこから利用可能です。
このNetwork Link Conditionerを利用すれば、帯域幅の制限やパケロス率の設定などを簡単に実現できます。
ただし、UDPパケットを全部落としつつ、TCPパケットについて帯域幅やパケロス率を設定したいという複雑なネットワーク環境を再現するためにはNetwork Link Conditionerだけでは実現できませんでした。
そこで、macOSにある、packet filterとdummynetを組み合わせることでこのような複雑なネットワーク環境を再現できました。
この記事ではpacket filterやdummynetの仕組みを紹介しつつ、どのように設定すれば、このような複雑なネットワーク環境を再現できるかをご紹介します。
実際 、Network Link Conditionerはpacket filterやdummynetをGUIからうまく設定できるような感じになっています。
packet filter(pf)
packet filter(pf)は、TCP/IPのフィルタリングとアドレス変換行うOpenBSDでの仕組みです。
macOSはBSD系OSなので、pfを使うことでTCP/IPのフィルタリングを行うことになります。(iptablesとかではない)
pf.conf
packet filterの設定ファイルになります。
ここでパケットフィルターの設定をします。
macOSだと、/etc/pf.conf
というファイルが最初からあるかと思います。
ここでは、 pf.conf
において、パケットフィルタリングについての設定についてのみ言及します。
特定のIPアドレスからのUDPパケットを落とす設定例は下記のとおりです。
block return in proto udp from 192.0.2.1 to any
アクション(1つ目の区切り) パケットをブロックするための
block
というアクションを指定しています。 2つ目の指定でreturn
としていますが、これは、tcpパケットに対して TCP RST を返し、UDP およびその他のパケットに対して ICMP UNREACHABLE を返すようにするという指定です。 単純に落とすだけであれば、drop
を指定してください。in以降のオプション
in
( またはout
) を指定することで、 受信パケット(送信パケット)を対象にするかを指定します。
proto
で対象となるprotocolを指定します。今回は udp
を指定しています。
from と toでそれぞれ、送信元アドレスやポート 宛先アドレスやポートを指定します。
他でできることは、 man pf.conf
で確認してもらえると。
他にもアクションは様々設定できます。
pfctlコマンドとオプション(抜粋)
pfctlコマンドを利用して、packet filterの状況やpf.confの反映を行います。
確認オプション
-s
のあとに続く文字列で取得できるもの選べます。
-v
をつけることでより詳細な情報をみれるのと、-v
を複数回書くことで詳細度が上がります。
気をつけたいのは、 -vvv
とかではなく、 -v -v
などと複数回書く必要があることです。
-si
or -s info
filterの統計情報などが見れます
-sr
or -s rules
現在ロードされているルールを表示します。
反映
-f
でルールの反映を行います。 ファイル or 標準出力でも可能。
n
をつけることで実際には反映させずparseだけ行うようにできます。
sudo pfctl -f /etc/pf.conf
dummynetとdnctlコマンド
dummynetは帯域のコントロール、ネットワークトラッフィクの遅延やパケロス率の制御などを行えるネットワークのエミュレーターです。
いわるゆtraffic shaperですね。
BSD系のOSに組み込まれており、macOSにも標準でインストールされています。
このdummynetはdnctlコマンドで制御を行います。
dnctlコマンドではpipeを使って帯域幅、遅延、キューサイズ、パケロス率を設定できます。
コマンド例
dnctl pipe 1 config delay 250ms bw 1Mbit/s plr 0.1
ここでは、遅延250 ms 、帯域幅 1M bit/s、パケロス率10%を pipe 1に設定するコマンドになっています。
dnctlだけではこの設定はつかわれません。
packet filterを使ってdummynetの設定にトラフィックを流すようにします。
この設定については、dnctlのmanにしかなく、pf.confのmanには記載されていないので要注意です。
pf.confには下記のように設定します
dummynet in quick proto tcp all pipe 1
この場合tcpのパケットがpipe 1のdummynetを通ることになります。
dnctlで設定した内容は
dnctl pipe show
こんな感じで見れます。
全部合わせてみると
UDPパケットを全部落として、TCPパケットについてはパケロス10%遅延250ms 帯域 1M bit /s にしてみます。
dnctlで下記を設定
dnctl pipe 1 config delay 250ms bw 1Mbit/s plr 0.1
pf.confには下記を設定
block return in proto udp from 192.0.2.1 to any dummynet out quick proto tcp all pipe 1
参考
パケットフィルタ規則の構文 - Oracle® Solaris 11.3 でのネットワークのセキュリティー保護
http://info.iet.unipi.it/~luigi/dummynet/
https://www.jstage.jst.go.jp/article/itej/64/10/64_1473/_pdf