最近、SYNフラッディングが原因で応答が非常に遅いApacheサーバーがありました。これの回避策は、tcp_syncookies(net.ipv4.tcp_syncookies=1 in /etc/sysctl.conf
)を有効にすることでした。
私はこれについて質問を投稿しました ここ より多くの背景が必要な場合。
Syncookiesを有効にした後、約60秒ごとに/ var/log/messagesに次のメッセージが表示されるようになりました。
[84440.731929] possible SYN flooding on port 80. Sending cookies.
Vinko Vrsalovicから、synバックログがいっぱいになっていることを通知されたため、tcp_max_syn_backlogを4096に上げました。ある時点で、sysctl -w net.ipv4.tcp_synack_retries=3
を発行してtcp_synack_retriesを3(デフォルトの5から下げた)に下げました。これを実行した後、メッセージの間隔が約60〜180秒の間で変化し、頻度が低下したように見えました。
次にsysctl -w net.ipv4.tcp_max_syn_backlog=65536
を発行しましたが、まだログにメッセージが表示されています。
この間、私はSYN_RECV状態の接続の数を(watch --interval=5 'netstat -tuna |grep "SYN_RECV"|wc -l'
を実行して)監視してきましたが、バックログのサイズよりもはるかに低く、約240を超えることはありません。しかし、私はRed Hatサーバーを持っていますが、これは約512をホバーします(このサーバーの制限はデフォルトの1024です)。
バックログのサイズを制限する他のtcp設定はありますか、それとも間違ったツリーを呼び出していますか? netstat -tuna
のSYN_RECV接続の数は、バックログのサイズと相関関係がありますか?
ここで正当な接続を扱っていることを伝えることができるので、netstat -tuna|wc -l
は5000程度に留まります。本日調査したところ、 this post を見つけたlast.fm従業員から、かなり役に立ちました。
また、syncookiesが有効になっている場合、tcp_max_syn_backlogは効果がないことも発見しました( this link に従って)
したがって、次のステップとして、sysctl.confに次のように設定します。
net.ipv4.tcp_syn_retries = 3
# default=5
net.ipv4.tcp_synack_retries = 3
# default=5
net.ipv4.tcp_max_syn_backlog = 65536
# default=1024
net.core.wmem_max = 8388608
# default=124928
net.core.rmem_max = 8388608
# default=131071
net.core.somaxconn = 512
# default = 128
net.core.optmem_max = 81920
# default = 20480
次に、応答時間テストをセットアップし、sysctl -p
を実行し、sysctl -w net.ipv4.tcp_syncookies=0
によってsyncookiesを無効にしました。
これを行った後も、SYN_RECV状態の接続数は約220〜250のままでしたが、接続は再び遅延し始めていました。これらの遅延に気付いたら、syncookiesを再度有効にすると遅延が停止しました。
私が見ていたことは、まだ初期状態からの改善であると思いますが、一部のリクエストはまだ遅延しており、syncookiesを有効にするよりもはるかに悪いです。そのため、負荷に対処するためにさらにいくつかのサーバーをオンラインにすることができるまで、それらを有効にしたままになっているように見えます。それでも、サーバーのバッファーがいっぱいになった場合にのみ(明らかに)送信されるため、それらを再び無効にする正当な理由があるかどうかはわかりません。
ただし、SYN_RECV状態の接続が250以下にすぎないため、synバックログがいっぱいになっていないようです。 SYNフラッディングメッセージがレッドニシンであり、syn_backlog以外のものがいっぱいになっている可能性はありますか?
まだ試していない他の調整オプションを誰かが持っている場合、私はそれらを試して満足しますが、syn_backlog設定が何らかの理由で適切に適用されていないのではないかと考え始めています。
だから、これはきちんとした質問です。
最初に、SYN Cookieが有効になっているSYN_RECV状態のany接続を目にして驚いた。 SYN Cookieの優れた点は、TCP暗号化を使用するサーバーとしての3ウェイハンドシェイクにステートレスに参加できることです。そのため、サーバーがハーフオープン接続をまったく表さないことを期待します。それは維持されていない状態とまったく同じです。
実際、ソース(tcp_ipv4.c)をざっと見ると、カーネルがSYN Cookieを実装する方法に関する興味深い情報が表示されます。基本的に、それらをオンにしても、カーネルは、保留中の接続のキューがいっぱいになるまで通常どおりに動作します。これは、SYN_RECV状態の既存の接続リストを説明します。
保留中の接続のキューがいっぱいで、別のSYNパケット(接続試行)が受信され、かつ最後の警告メッセージから1分以上経過している場合にのみ、カーネルは表示された警告メッセージを送信します( "cookiesの送信") )。警告メッセージが送信されない場合でも、SYN Cookieは送信されます。警告メッセージは、問題が解消されていないことを示すためのものです。
言い換えると、SYN Cookieをオフにすると、メッセージは消えます。これは、SYNフラッディングが発生しなくなった場合にのみ機能します。
あなたが行った他のいくつかのことに取り組むには:
net.ipv4.tcp_synack_retries
:net.ipv4.tcp_syn_retries
:これを変更しても、インバウンド接続には影響しません(アウトバウンド接続にのみ影響します)あなたが言及している他の変数については調査していませんが、あなたの質問に対する答えはほぼここにあると思います。
SYNフラッディングが発生しておらず、マシンがHTTP以外の接続(SSHなど)に応答している場合、おそらくネットワークに問題があると思います。ネットワークエンジニアに調べてもらう必要があります。 SYNフラッドが発生していないのにマシンが一般的に応答しない場合、TCP接続の作成に影響を与えるとかなりの負荷問題のように聞こえます(かなり低レベルでリソースに負荷がかかりません)。
Webサーバー(Apache2)を実行して負荷の高いWebサイトを実行しているUbuntu Oneiric 11.10の新規インストールでも、まったく同じ問題に直面しました。 Ubuntuでは、Oneiric 11.10のsyncookiesがデフォルトで有効になっています。
WebサーバーポートでのSYNフラッド攻撃の可能性を示す同じカーネルメッセージがありました。
カーネル:[739408.882650] TCP:ポート80でのSYNフラッディングの可能性。Cookieの送信。
同時に、攻撃が発生していないことは確かでした。このメッセージは5分間隔で返されました。これは、負荷のピークのように見えました。攻撃者は、サーバーが要求に応答するのを止めようとしている間、常に負荷を高く保つからです。
net.ipv4.tcp_max_syn_backlog
パラメータを調整しても改善は見られませんでした。メッセージは同じ速度で継続しました。 SYN_RECV接続の数が常に非常に少ない(私の場合は250未満)という事実は、このメッセージの原因となる他のパラメーターが存在する必要があることを示すものでした。
Red Hatサイトでこのバグメッセージ https://bugzilla.redhat.com/show_bug.cgi?id=734991 を見つけ、カーネルメッセージはバグの結果である可能性があると述べました(または構成ミス)アプリケーション側。もちろん、ログメッセージは非常に誤解を招くものです!これは、その場合に責任があるカーネルパラメータではなく、アプリケーションのパラメータであるため、カーネルに渡されます。
したがって、Webサーバーアプリケーションの構成パラメーターも確認する必要があります。 Apacheドキュメントを取得して http://httpd.Apache.org/docs/2.0/mod/mpm_common.html#listenbacklog にアクセスします
ListenBacklog
パラメータのデフォルト値は511です(これは、Red Hatサーバーで確認した接続の数に対応します。別のサーバーで設定されている数が少ない可能性があります)。
Apacheには、着信接続のバックログキュー用の独自の構成パラメーターがあります。多くの着信接続があり、いつでも(ちょうどランダムなものとして)それらがほぼ同時に到着し、Webサーバーが適切な方法で十分に高速に接続を提供できない場合、バックログは511接続でいっぱいになると、カーネルはSYNフラッド攻撃の可能性を示す上記のメッセージを発行します.
これを解決するには、次の行を/etc/Apache2/ports.conf
またはApacheによってロードされる他の.confファイルの1つに追加します(/etc/Apache2/Apache2.conf
も問題ないはずです)。
ListenBackLog 5000
また、net.ipv4.tcp_max_syn_backlog
を適切な値に設定する必要があります。私の理解では、カーネルの最大値によって値が制限され、Apache構成で構成できるようになります。だから実行:
Sudo sysctl -w net.ipv4.tcp_max_syn_backlog=5000
設定を調整したら、Apacheを再起動することを忘れないでください。
Sudo service Apache2 restart ( or Sudo /etc/init.d/Apache2 restart )
私の場合、この構成変更により、カーネル警告がすぐに停止しました。 Apacheの設定でListenBackLogの値を低く設定することで、メッセージを再現できます。
カーネル3.4.9でのいくつかのテストの後、netstatのSYN_RECV接続の数は
/proc/sys/net/core/somaxconn
2の次のべき乗に切り上げられます(例:128-> 256)/proc/sys/net/ipv4/tcp_max_syn_backlog
が/proc/sys/net/ipv4/tcp_syncookies
に設定されている場合は0
の75%、/proc/sys/net/ipv4/tcp_syncookies
が1
に設定されている場合は100%ListenBackLog
は、2の累乗に切り上げられます(例:128-> 256)この各パラメーターの最小値が使用されます。 somaxconnまたはListenBackLogを変更した後、Apacheを再起動する必要があります。
そしてtcp_max_syn_backlogを増やした後、Apacheも再起動する必要があります。
Tcp_syncookiesがないと、Apacheがブロックします。この場合、tcp_max_syn_backlogの75%だけが制限である理由はおかしいです。このパラメータを増やすと、Apacheを再起動せずにSYN_RECV接続を古い値の100%に増やします。