Quantcast
Channel: bogamp’s blog
Viewing all articles
Browse latest Browse all 34

Linuxでnftablesを使用してレートリミットを設定する

$
0
0

レートリミットとは通信量の制限のこと。ここではアプリケーションレベルのレートリミットではなく、OS全体のレートリミットについて扱う。
Linuxにおけるレートリミットは、1.ファイアウォールiptablesやnftables)か、2.トラフィック制御(tcコマンド)を用いて設定することができる。
ここでは1のうち、nftablesを用いたレートリミットの設定を扱う。

1.nftablesによるレートリミットの設定方法

参考リンク:https://wiki.nftables.org/wiki-nftables/index.php/Rate_limiting_matchings
当然だが、ファイアウォールに他のルールを設定している場合は、ルールの順番を間違えたりすると意味がなくなるので注意すること。
nftablesの他の機能と組み合わせれば、送信先ポートや送信元アドレスごとのリミットレートも設定できる。

1.1 基本

nft add rule inet filter input limit rate 10 mbytes/second accept
nft add rule inet filter input drop

limit rateのキーワードを使うと、指定した通信量以下のパケットのみにマッチさせることができる。上のルールで、1秒につき10メガバイトまではacceptし、その基準を超えたパケットは下のルールによってdropされる。
(ちなみに、パケットを廃棄してしまうと確立した接続が途中で突然切れないか心配になるかもしれない。しかし、TCPの仕様でパケットはすぐに再送されるので、接続がいきなりブツッと切れるみたいなことはそんなにないはず)
パケット数で指定することもできる。

nft add rule inet filter input limit rate 100/second accept
nft add rule inet filter input drop

1.2 burst

burstを使うと、一時的な通信量の増加を受け入れることもできる。
nft add rule inet filter input limit rate 10 mbytes/second burst 9000 kbytes accept
nft add rule inet filter input drop

1秒につき10メガバイトの通信量を超えたときも、あと9000キロバイトまでなら一時的に許可される(あくまで一時的なので、常時この通信量が許可されるわけではない)

1.3 limit rate over

単にlimit rateの場合は指定した通信量以下の場合にマッチするルールになったが、limit rate overの場合は指定した通信量を超えたときにマッチするルールになる。
nft add rule inet filter input limit rate over 10 mbytes/second drop

こちらを使ってdropしたほうがシンプルで、使い勝手が良いかもしれない。
burstも設定できる。

nft add rule inet filter input limit rate over 10 mbytes/second burst 9000 kbytes drop

1.4 速度計測

設定したルールが上手く動いているか確認したいときは、https://www.speedtest.netなどのサイトで手軽に速度を確認することができる。
仮想OS等を使って、iperf3などで計測してみるのも良い。
注意点として、通信速度によく使われる単位である「Mbps」(bが小文字)は、一秒あたりの通信量をメガビット(メガバイトではなく)で表したものであることには気をつけること。

1.5 IPアドレスごとの通信量制限

参考リンク:
https://wiki.nftables.org/wiki-nftables/index.php/Meters
https://www2.filewo.net/wordpress/2019/10/19/2206/

setを用いることでIPアドレスごとのレートリミットの設定が可能になる。

nft add set inet filter rate_limit_ip {type ipv4_addr \; flags dynamic \; timeout 10m \;}
nft add rule inet filter input update @rate_limit_ip { ip saddr limit rate over 10 mbytes/second } drop

まずIPアドレスのsetを作成する。このときflags dynamic \; を指定するのがポイントで、動的にアドレスを管理できるようになる。
(timeoutはsetが溢れないために設定しておく)
@をつけてsetを呼び出し、随時updateすることでIPアドレスごとのレートリミットが設定できる。
IPv6も同様に設定できる。

nft add set inet filter rate_limit_ipv6 {type ipv6_addr \; flags dynamic \; timeout 10m \;}
nft add rule inet filter input update @rate_limit_ipv6 { ip6 saddr limit rate over 10 mbytes/second } drop

2.ルールセットの例

レートリミットを使用したnftablesルールセットをいくつか書いておく。

2.1 SSHサーバへの新規接続に制限を設けた例

table inet filter {
	chain input {type filter hook input priority filter; policy drop;
		ct state established,related accept
		ct state invalid drop
		iif "lo" accept
		meta l4proto icmp accept
		meta l4proto ipv6-icmp accept
		tcp dport 22 ct state new limit rate over 20/minute drop
		tcp dport 22 accept
	}

	chain forward {type filter hook forward priority filter; policy drop;}

	chain output {type filter hook output priority filter; policy accept;}}

2.2 HTTP(HTTPS)サーバで同一アドレスからの通信量と新規接続を制限した例

table inet filter {set rate_limit_ip {type ipv4_addr		size 65535		flags dynamic,timeout		timeout 10m}set rate_limit_ipv6 {type ipv6_addr		size 65535		flags dynamic,timeout		timeout 10m}set rate_limit_newconnection_ip {type ipv4_addr		size 65535		flags dynamic,timeout		timeout 10m}set rate_limit_newconnection_ipv6 {type ipv6_addr		size 65535		flags dynamic,timeout		timeout 10m}
	chain input {type filter hook input priority filter; policy drop;
		ct state established,related accept
		ct state invalid drop
		iif "lo" accept
		meta l4proto icmp accept
		meta l4proto ipv6-icmp accept
		tcp dport {80, 443} update @rate_limit_ip { ip saddr limit rate over 20 mbytes/second } drop
		tcp dport {80, 443} update @rate_limit_ipv6 { ip6 saddr limit rate over 20 mbytes/second } drop
		tcp dport {80, 443} ct state new update @rate_limit_newconnection_ip { ip saddr limit rate over 20/second } drop
		tcp dport {80, 443} ct state new update @rate_limit_newconnection_ipv6 { ip6 saddr limit rate over 20/second } drop
		tcp dport {80, 443} accept
	}



	chain forward {type filter hook forward priority filter; policy drop;}

	chain output {type filter hook output priority filter; policy accept;}}

3. 参考リンク

https://wiki.nftables.org/wiki-nftables/index.php/Main_Page
https://netfilter.org/projects/nftables/manpage.html
https://wiki.archlinux.jp/index.php/Nftables

Viewing all articles
Browse latest Browse all 34

Trending Articles