computerの日記

Cisco,SHELL,C,Qt,C++,Linux,ネットワーク,Windows Scriptなどの発言です

backlog の実験

こんにちは、ちょっと涼しくなってきましたね。

今日は、backlog の実験をしてみます。

CentOS6.9 で、メモリ4Gbyte の仮想マシン上で実験しました。

よく使われるアプリケーションとして、Apache を上げてみます。

前提知識です。

syn backlog:接続確立中キューの最大値(不完全なソケットのキューの最大長)

backlog:接続待ちキューの最大値(完全に確立されたソケットのキューの最大長)

tcp_syncookies:

有効(値 1):一定の基準を越えた場合、syncookies を送信する。
syn backlog と backlog の小さいほうの値を、付近の 2の累乗の値に
切り上げた数値を超えると、syncookie を送信します(注)。
その際、ソケット蓄積の概念は放棄されるため、syn backlogの最大値の概念
は無視されます。

無効(値 0): 一定の基準を越えた場合、新たな要求を無視する。
接続確立中キューに syn backlog の 75 % + 1 を超えるソケットが溜まる
と、新しい要求を無視します。

(注)
syncookies は、TCP プロトコルにしたがっていない点があり、攻撃に対する
対処用法として存在し、予備的な機能(fallback functionality)でしか
ないため、SYN flood を起こさせるようなDOS 攻撃を受けていると考えられる
場合のみに発動されるべきです。
(参考)
Documentation/networking/ip-sysctl.txt

次に、それぞれの値の設定ヶ所の説明です。

- syn backlog の設定ヶ所
OS の設定か所:/proc/sys/net/ipv4/tcp_max_syn_backlog
Apache の設定ヶ所:なし

- backlog の設定ヶ所
OSの設定箇所: /proc/sys/net/core/somaxconn
Apache の設定か所: ListenBackLog ディレクティブの設定値

backlog の値について、OS および Apache で設定が可能ですが、以下の条件にしたがいます。

Apache の設定値 ≦ OS の設定値ならば、
Apache の設定値が有効

Apache の設定値 > OS の設定値ならば、
OS の設定値が有効

- tcp_syncookies の設定ヶ所
OS の設定か所:/proc/sys/net/ipv4/tcp_syncookies
Apache の設定ヶ所:なし

backlog の値は、実際は 1 から 65535 まで設定可能です。

例えば、OS および Apache の設定値を 4096 にすると、backlog の設定値は、
Apache の値、4096 となります。

syn backlog の値を増やすかどうかは、そのマシンの通常の通信状況によります。

OS のデフォルト設定では、syncookies が有効になっていますので、
接続確立中の要求が syn backlog の値と、backlog 値の小さいほうの値を、
付近の 2 の累乗の値を切り上げた数値を超えた場合、syncookie が送信されます。

通常のトラフィックにおいて、接続確立中の要求が多くならいようであれば、
syn backlog の値を増やす必要はなく、通常の通信環境においても、
接続確立中の要求が多くなるようであれば、多くする必要があるかもしれませんね。

いずれにしても、設定の際は、通常のアプリケーションの通信状況を把握した上で、
各上限値を設定する必要があるといえます。

TCP ソケットを listen している情報は、以下のコマンドの結果が表示する、
Recv-Q,Send-Q により確認できます。ここで、Send-Q の値が、Apache
backlog になります。

 

# ss -lti '( sport = :http )'

 

接続確立中の要求数の確認は、以下のコマンドで確認できます。

 

# netstat -antp | grep SYN_RECV | wc -l

 

(一例:syncookies=0 で syn backlog が 2048 の時、上限値に達した場合)
1537

 

私が行った設定で実験したら、このようになりました。
--------
・デフォルトの設定

128 /proc/sys/net/core/somaxconn
2048 /proc/sys/net/ipv4/tcp_max_syn_backlog
511 Apache の ListenBackLog ディレクティブ

backlog の最大値 128
tcp_syncookies=1 の場合
接続確立中の要求数の上限値 256(backlog の付近の2の累乗の値)
tcp_syncookies=0 の場合
接続確立中の要求数の上限値 1537(syn backlog * 0.75 + 1 の値)

・OS、Apache の設定値を上げる

2048 /proc/sys/net/core/somaxconn
2048 /proc/sys/net/ipv4/tcp_max_syn_backlog
2048 Apache の ListenBackLog ディレクティブ

backlog の最大値 2048
tcp_syncookies=1 の場合
接続確立中キューの最大値 4096(backlog の付近の2の累乗の値)
tcp_syncookies=0 の場合
接続確立中キューの最大値 1537(syn backlog * 0.75 + 1 の値)

・syn backlog 変化させず、さらにOS、Apacheの設定値を上げる

4096 /proc/sys/net/core/somaxconn
2048 /proc/sys/net/ipv4/tcp_max_syn_backlog
4096 Apache の ListenBackLog ディレクティブ

backlog の最大値 4096
tcp_syncookies=1 の場合
接続確立中キューの最大値 4096(syn backlog の付近の 2 の累乗の値)
tcp_syncookies=0 の場合
接続確立中キューの最大値 1537(syn backlog * 0.75 + 1 の値)

・syn backlog を、4096 に上げる

4096 /proc/sys/net/core/somaxconn
4096 /proc/sys/net/ipv4/tcp_max_syn_backlog
4096 Apache の ListenBackLog ディレクティブ

backlog の最大値 4096
tcp_syncookies=1 の場合
接続確立中キューの最大値 8192(backlog の付近の2の累乗の値)
tcp_syncookies=0 の場合
接続確立中キューの最大値 3073(syn backlog * 0.75 + 1 の値)

 

また、この実験の場合ですが、接続確立中の要求が syn backlog の値と、
backlog 値の小さいほうの値を、付近の 2 の累乗の値を切り上げた数値を超えた
場合、syncookie が送信されることになります。
そのとき、/va/log/messages には、以下のログが 60秒に 1回記録されます。

kernel: possible SYN flooding on port <PORT>. Sending cookies.

 

tcp_syncookies は OS で有効に設定されています。
tcp_syncookies が有効な場合、上述のとおり syn backlog の値を
変化させることにより、接続確立中キューの最大値は変化するので、

適宜設定したらいいと思います。

 

 具体的にどうやって実験したかというと、次のようにやりましたよ。

以下のスクリプトを実行します。これを確認します。

#!/bin/bash
while :
do
netstat -antp | grep SYN_RECV | wc -l

sleep 1
done

 

下記のとおり、SYN FLOOD 攻撃を実行して、上記の表示を観察する(実際のシステムにやってはいけませんよ)。

 

# hping3 -c 10000 -d 120 -S -w 64 -p 21 --flood --rand-source <TARGET_IP>

 

おいしいもの食べたいなぁ。

 

(参考:用語解説等)

https://access.redhat.com/solutions/30453

http://d.hatena.ne.jp/nyant/20111216/1324043063

mpm_common - Apache HTTP サーバ バージョン 2.4

(参考:hping3)
https://www.blackmoreops.com/2015/04/21/denial-of-service-attack-dos-using-hping3-with-spoofed-ip-in-kali-linux/