NGINX は、高性能ロード バランサ、キャッシュ、Web サーバーで知られており、世界で最もアクセス数の多い Web サイトの 40% 以上に電力を供給しています。 has 一定の参考値があります。困っている友達が参考にできます。皆さんのお役に立てれば幸いです。
1. Nginx モジュールと動作原理
基本モジュール:
HTTP Access モジュール、HTTP FastCGI モジュール、HTTP プロキシ モジュール、HTTP Rewrite モジュール、3-パーティ モジュール:
HTTP アップストリーム リクエスト ハッシュ モジュール、通知モジュール、および HTTP アクセス キー モジュール。ユーザーが独自のニーズに応じて開発したモジュールは、サードパーティ モジュールです。 Nginx の機能が非常に強力なのは、まさに多くのモジュールのサポートがあるからです。Nginx モジュールは機能的に次の 3 つのカテゴリに分類されます。
ハンドラー (プロセッサー モジュール)。このタイプのモジュールはリクエストを直接処理し、コンテンツの出力やヘッダー情報の変更などの操作を実行します。通常、存在できるハンドラー プロセッサ モジュールは 1 つだけです。
フィルター (フィルター モジュール)。このタイプのモジュールは主に他のプロセッサ モジュールによって出力されたコンテンツを変更し、最終的に Nginx によって出力されます。
プロキシ (プロキシ クラス モジュール)。このようなモジュールは、Nginx の HTTP Upstream などのモジュールであり、主に FastCGI などの一部のバックエンド サービスと対話して、サービス プロキシやロード バランシングなどの機能を実装します。
図 1-1 は、Nginx モジュールの通常の HTTP リクエストとレスポンスのプロセスを示しています。
##Nginx 自体は実際にはほとんど機能しません。HTTP リクエストを受信すると、設定ファイルを検索するだけです。このリクエストはマップされます。を location ブロックに追加すると、この場所に設定された各命令が作業を完了するために異なるモジュールを開始するため、モジュールは Nginx の実際の労働者とみなすことができます。通常、ある場所の命令には、ハンドラー モジュールと複数のフィルター モジュールが含まれます (もちろん、複数の場所で同じモジュールを再利用できます)。ハンドラー モジュールはリクエストの処理と応答コンテンツの生成の完了を担当し、フィルター モジュールは応答コンテンツを処理します。
Nginx モジュールは Nginx に直接コンパイルされるため、静的コンパイル方法となります。 Nginx を起動すると、Nginx モジュールが自動的にロードされますが、Apache とは異なり、まずモジュールを so ファイルにコンパイルしてから、ロードするかどうかを設定ファイルで指定します。設定ファイルを解析するとき、Nginx の各モジュールは特定のリクエストを処理できますが、同じ処理リクエストは 1 つのモジュールでのみ完了できます。
2. Nginx プロセス モデル
マスター プロセスは主にワーカー プロセスの管理に使用され、次の 4 つの主要な機能が含まれます:
(1) からのシグナルを受信します。外の世界。
(2) 各ワーカープロセスにシグナルを送信します。
(3) ワーカープロセスの実行状態を監視します。
(4) ワーカー プロセスが終了すると (異常な状況下で)、新しいワーカー プロセスが自動的に再起動されます。
ユーザー対話インターフェイス:マスター プロセスは、プロセス グループ全体とユーザー間の対話インターフェイスとして機能し、プロセスの監視も行います。ネットワーク イベントを処理する必要はなく、ビジネスの実行も担当せず、サービスの再起動、スムーズなアップグレード、ログ ファイルの置換、リアルタイムで有効になる構成ファイルなどの機能を実装するためのワーカー プロセスを管理するだけです。
ワークプロセスを再起動します:nginx を制御するには、kill を通じてマスタープロセスにシグナルを送信するだけです。たとえば、kill -HUP pid は nginx に nginx を正常に再起動するように指示します。通常、この信号は nginx を再起動するか、設定をリロードするために使用されます。正常に再起動されるため、サービスは中断されません。
HUP 信号を受信した後、マスター プロセスは何をしますか?
1). まず、シグナルを受信した後、マスター プロセスは構成ファイルをリロードし、新しいワーカー プロセスを開始し、すべての古いワーカー プロセスにシグナルを送信して、それらが可能であることを伝えます。素晴らしい、引退した。
2). 新しいワーカーは開始後、新しいリクエストの受信を開始しますが、古いワーカーはマスターからのシグナルを受信した後に新しいリクエストの受信を停止し、現在のプロセスで未処理のリクエストがすべて処理された後、出口。
マスター プロセスに信号を直接送信します。これはより伝統的な操作方法です。nginx バージョン 0.8 以降、管理を容易にするために一連のコマンド ライン パラメーターが導入されました。たとえば、./nginx -s reload は nginx を再起動し、./nginx -s stop は nginx の実行を停止します。 ###どうやってするの?リロードを例に挙げると、コマンドの実行時に新しい nginx プロセスが開始され、新しい nginx プロセスがリロード パラメータを解析した後、目的が設定ファイルをリロードするように nginx を制御することであることがわかります。マスター プロセスにシグナルを送信すると、次のアクションはマスター プロセスにシグナルを直接送信した場合と同じになります。
ワーカー プロセスは平等であり、各プロセスにはリクエストを処理する同じ機会があります。ポート 80 で http サービスを提供し、接続要求が来た場合、各プロセスが接続を処理する場合があります。
Nginx は、Libevent と同様に、非同期のノンブロッキング メソッドを使用してネットワーク イベントを処理します。具体的なプロセスは次のとおりです:
1) リクエストの受信:まず、それぞれのリクエストを受信します。ワーカープロセス マスタープロセスからフォークされ、マスタープロセスはリッスンする必要のあるソケット (listenfd) を確立した後、複数のワーカープロセスをフォークアウトします。新しい接続が到着すると、すべてのワーカー プロセスの listenfd が読み取り可能になり、各ワーカー プロセスはこのソケット (listenfd) を受け入れることができます。クライアント接続が到着すると、すべての受け入れワークプロセスに通知されますが、正常に受け入れられるのは 1 つのプロセスのみで、他のプロセスは受け入れに失敗します。 1 つのプロセスのみが接続を処理できるようにするために、Nginx は共有ロック accept_mutex を提供し、同時に 1 つのワークプロセスのみが接続を受け入れるようにします。すべてのワーカー プロセスは、listenfd 読み取りイベントを登録する前に accept_mutex を取得します。ミューテックス ロックを取得するプロセスは、listenfd 読み取りイベントを登録し、読み取りイベントで accept を呼び出して接続を受け入れます。
2) リクエストの処理:ワーカー プロセスは接続を受け入れた後、リクエストの読み取り、リクエストの解析、リクエストの処理、データの生成を開始し、データをクライアントに返します。最後に、切断するだけです。完全なリクエストは次のようになります。リクエストはワーカー プロセスによって完全に処理され、1 つのワーカー プロセスでのみ処理されることがわかります。ワーカー プロセスは平等であり、各プロセスにはリクエストを処理する同じ機会があります。
nginx のプロセス モデルは次の図で表すことができます:
nginx はマルチワーカー方式を使用してリクエストを処理しますが、各ワーカーにはメイン スレッドが 1 つしかないため、処理できる同時実行数は非常に限られています。できるだけ多くのワーカーで同時実行数を処理できます。では、どうすれば高い同時実行性を実現できるのでしょうか?いいえ、これが nginx の優れた点です。
nginx は、非同期でノンブロッキングのメソッドを使用してリクエストを処理しますつまり、nginx はリクエストを次の時点で処理できます。同時に何千ものリクエストがありました。ワーカー プロセスが同時に処理できるリクエストの数はメモリ サイズによってのみ制限され、アーキテクチャ設計の観点からは、異なるワーカー プロセス間で同時リクエストを処理する場合の同期ロックに関する制限はほとんどありません。通常、ワーカー プロセスはスリープ状態に入らないため、Nginx 上のプロセスの数が CPU コアの数と等しい場合 (各ワーカー プロセスが特定の CPU コアにバインドされることが最適です)、プロセス間の切り替えは最小限です。## そして、Apache の一般的な動作方法 (Apache には非同期のノンブロッキング バージョンもありますが、独自のモジュールの一部と競合するため、一般的には使用されません)。
,したがって、同時実行数が数千に達すると、数千のプロセスがリクエストを処理することになります。同時。これはオペレーティング システムにとって大きな課題です。processによるメモリ使用量は非常に多くなります。processのコンテキスト切り替えにより多くの CPU オーバーヘッドが発生するため、パフォーマンスは自然に向上します。 . 行かなければ出費は全く意味がありません。
# nginx が非同期のノンブロッキング メソッドで処理できる理由、または非同期メソッドで何が起こったのかノンブロッキング?詳細については、「libevent と libev を使用してネットワーク アプリケーションのパフォーマンスを向上させる - I/O モデルの進化の歴史」を参照してください。 原点に戻って、リクエストの完全なプロセスを見てみましょう。まず、リクエストが送信されます。接続を確立する必要があるため、データを受信し、データを受信してからデータを送信します。 システムの最下位層に特有の、読み取りイベントと書き込みイベントです。読み取りイベントと書き込みイベントの準備ができていないときは、動作不能でなければなりません。非ブロッキングな方法で呼び出さない場合は、 、通話をブロックする必要があり、イベントの準備ができていない場合は、待つことしかできません。イベントの準備ができたら、続行できます。呼び出しをブロックするとカーネルに入って待機し、CPU が他のユーザーによって使用されることになります。シングルスレッドのワーカーには明らかに適していません。ネットワーク イベントが増えると全員が待機し、CPU が使用されているときは誰も CPU を使用しません。 CPU 使用率 当然のことながら、高い同時実行性はおろか、レートを上げることもできません。さて、プロセスの数を増やすとおっしゃいましたが、これと Apache のスレッド モデルの違いは何ですか? 不必要なコンテキスト スイッチングを増やさないように注意してください。したがって、nginxではシステムコールのブロックは最もタブーとされています。ブロックしない場合は、ノンブロッキングになります。ノンブロッキングとは、イベントの準備ができていない場合に、すぐに EAGAIN に戻り、イベントの準備がまだできていないことを通知することを意味します。なぜパニックになっているのですか? 後で戻ってください。しばらくしてから、イベントの準備ができるまでもう一度イベントを確認してください。この期間中は、先に他の作業を行ってから、イベントの準備ができているかどうかを確認できます。ブロックされなくなりましたが、イベントのステータスを時々確認する必要があり、できることは増えましたが、オーバーヘッドは小さくありません。IO モデルについて: http://blog.csdn.net/hguisu/article/details/7453390
nginx でサポートされているイベント モデルは次のとおりです。以下に続きます (nginx wiki):
Nginx では、接続を処理するための次のメソッド (I/O 多重化メソッド) がサポートされており、これらのメソッドは use ディレクティブを通じて指定できます。
Linux では、epoll のみが効率的な方法です。
epoll がどれほど効率的であるかを見てみましょう
Epoll は、大量のハンドルのバッチを処理するために Linux カーネルによって作成されます。 改善されました世論調査。 epoll を使用するには、epoll_create(2)、epoll_ctl(2)、epoll_wait(2) の 3 つのシステム コールだけが必要です。これは 2.5.44 カーネルで導入され (epoll(4) は Linux カーネル 2.5.44 で導入された新しい API)、2.6 カーネルで広く使用されています。
## Epoll の利点
従来の選択/ポーリングのもう 1 つの致命的な弱点は、大規模なソケット セットがある場合、ネットワーク遅延により、常に一部のソケットのみが「アクティブ」ですが、select/poll の呼び出しごとにコレクション全体が線形にスキャンされるため、効率が線形に低下します。しかし、epoll にはこの問題はなく、「アクティブな」ソケット上でのみ動作します。これは、カーネル実装では、epoll が各 fd のコールバック関数に基づいて実装されているためです。次に、「アクティブ」ソケットのみがコールバック関数をアクティブに呼び出し、他のアイドル状態のソケットは呼び出しません。この時点では駆動力は OS カーネルにあるため、epoll は「疑似」AIO を実装します。一部のベンチマークでは、高速 LAN 環境など基本的にすべてのソケットがアクティブな場合、epoll は select/poll よりも効率的ではありませんが、逆に epoll_ctl を使いすぎると若干効率が低下します。ただし、アイドル接続を使用して WAN 環境をシミュレートすると、epoll の効率は select/poll の効率よりもはるかに高くなります。
この点は、実際には epoll の特定の実装に関係します。 select、poll、epoll のいずれであっても、カーネルは FD メッセージをユーザー空間に通知する必要があります。不必要なメモリのコピーをいかに避けるかが非常に重要です。この時点で、epoll は、ユーザー空間内の同じメモリを mmap することによって実装されます。カーネル。そして、私のように 2.5 カーネルから epoll をフォローしている場合は、手動の mmap ステップを決して忘れることはありません。
これは実際には epoll の利点ではなく、Linux プラットフォーム全体の利点です。 Linux プラットフォームを疑うかもしれませんが、Linux プラットフォームが提供するカーネルを微調整する機能を避けることはできません。たとえば、カーネル TCP/IP プロトコル スタックはメモリ プールを使用して sk_buff 構造を管理し、このメモリ プール (skb_head_pool) のサイズは実行時に動的に調整できます。これは echo XXXX>/proc/sys/net/core によって完了します。 /hot_list_length.もう 1 つの例は、listen 関数の 2 番目のパラメータ (TCP が 3 ウェイ ハンドシェイクを完了した後のパケット キューの長さ) です。これも、プラットフォームのメモリ サイズに応じて動的に調整できます。データ パケットの数は膨大ですが、各データ パケット自体のサイズは非常に小さい特別なシステムで、最新の NAPI ネットワーク カード ドライバー アーキテクチャを試してみました。
(epoll コンテンツ、epoll_Interactive Encyclopedia を参照)
ワーカーの数を CPU コアの数に設定することをお勧めします。ここでは非常に便利ですが、ワーカーが増えるとプロセスが CPU リソースをめぐって競合するだけになり、不必要なコンテキストの切り替えが発生することは容易に理解できます。さらに、マルチコア機能をより有効に活用するために、nginx には CPU アフィニティ バインド オプションが用意されており、特定のプロセスを特定のコアにバインドできるため、プロセスの切り替えによってキャッシュが失敗することはありません。このような小さな最適化は nginx では非常に一般的であり、これは nginx 作成者の骨の折れる努力を示しています。たとえば、nginxは4バイト文字列を比較する場合、CPUの命令数などを減らすために4文字をint型に変換して比較します。
nginx イベント処理モデルを要約するコード:
while (true) { for t in run_tasks: t.handler(); update_time(&now); timeout = ETERNITY; for t in wait_tasks: /* sorted already */ if (t.time <= now) { t.timeout_handler(); } else { timeout = t.time - now; break; } nevents = poll_function(events, timeout); for i in nevents: task t; if (events[i].type == READ) { t.handler = read_handler; } else { /* events[i].type == WRITE */ t.handler = write_handler; } run_tasks_add(t); }
FastCGI はスケーラブルで高速なインターフェイスですHTTP サーバーと動的スクリプト言語間の通信用。 Apache、Nginx、lighttpd など、最も一般的な HTTP サーバーは FastCGI をサポートしています。同時に、FastCGI は、PHP を含む多くのスクリプト言語でもサポートされています。
FastCGI は CGI を発展させて改良したものです。従来の CGI インターフェイス方式の主な欠点は、パフォーマンスが低いことです。これは、HTTP サーバーが動的プログラムに遭遇するたびに、スクリプト パーサーを再起動して解析を実行する必要があり、結果が HTTP サーバーに返されるためです。これは、同時アクセスが多い場合にはほとんど使用できません。また、従来の CGI インターフェース方式はセキュリティが低く、現在ではほとんど使用されていません。
FastCGI インターフェイス モードは C/S 構造を採用しており、HTTP サーバーとスクリプト解析サーバーを分離し、スクリプト解析サーバー上で 1 つ以上のスクリプト解析デーモンを起動できます。 HTTP サーバーが動的プログラムに遭遇するたびに、そのプログラムは実行のために FastCGI プロセスに直接配信され、その結果がブラウザーに返されます。この方法により、HTTP サーバーは静的リクエストを排他的に処理したり、動的スクリプト サーバーの結果をクライアントに返すことができるため、アプリケーション システム全体のパフォーマンスが大幅に向上します。
Nginx は、外部プログラムの直接呼び出しや解析をサポートしていません。すべての外部プログラム (PHP を含む) は必須です。 FastCGI インターフェイスを通じて呼び出すことができます。 FastCGI インターフェイスは、Linux 上のソケットです (このソケットはファイル ソケットまたは IP ソケットにすることができます)。
wrapper:CGI プログラムを呼び出すには、FastCGI ラッパーも必要です (ラッパーは、別のプログラムを開始するために使用されるプログラムとして理解できます)。このラッパーは固定ソケットにバインドされており、ポートやファイルソケットなど。 Nginx が CGI リクエストをこのソケットに送信すると、ラッパーは FastCGI インターフェイスを介してリクエストを受信し、新しいスレッドをフォーク (派生) します。このスレッドは、インタプリタまたは外部プログラムを呼び出してスクリプトを処理し、戻りデータを読み取ります。次に、ラッパーは返されたデータを FastCGI インターフェイスおよび固定ソケット経由で Nginx に渡し、最後に Nginx は返されたデータ (HTML ページまたは画像) をクライアントに送信します。図 1-3 に示すように、これは Nginx FastCGI の全体的な操作プロセスです。
したがって、最初にラッパーが必要です。このラッパーが完了する必要がある作業:
# FastCGI インターフェイス メソッドがスクリプトを開始します。スクリプト解析サーバーまたは複数のデーモン プロセスが動的スクリプトを解析します。これらのプロセスは、FastCGI プロセス マネージャーまたは FastCGI エンジンです。 spawn-fcgi と PHP-FPM は、PHP をサポートする 2 つの FastCGI プロセス マネージャーです。したがって、HTTPServer は完全に解放され、より適切に応答し、同時に処理できるようになります。
spawn-fcgi と PHP-FPM の類似点と相違点:
1) spawn-fcgi は HTTP サーバー lighttpd の一部であり、独立したプロジェクトとなっており、一般的にはlighttpd と組み合わせて使用されます。PHP がサポートされています。ただし、ligttpd の spwan-fcgi はメモリ リークを引き起こしたり、同時アクセスが多いときに FastCGI が自動的に再起動したりする可能性があります。つまり、PHP スクリプト プロセッサがクラッシュし、この時点でユーザーがアクセスすると、白いページが表示される可能性があります (つまり、PHP を解析できないか、エラーが発生します)。
2) Nginx は軽量の HTTP サーバーであり、PHP を解析するにはサードパーティの FastCGI プロセッサを使用する必要があります。非常に柔軟です。任意のサードパーティ解析プロセッサと接続して、PHP(設定が簡単)nginx.conf。nginx はspwan-fcgi も使用できます (はlighttpdと一緒にインストールする必要がありますが、nginxのポートは避けてください。以前のブログには、この点に関するインストール チュートリアルがあります)ですが、spawn-fcgiには上記のような欠陥が徐々にユーザーによって発見されてきたため、現在ではnginx spawn-fcgi# の使用は徐々に減少しています。##組み合わせたもの。spawn-fcgi の欠陥のため、現在はサードパーティ製 (現在 PHP コアに追加されている) PHP FastCGI プロセッサ PHP-FPM が使用されています。spawn-fcgi と比較すると、次のような利点があります。 :PHP パッチとして開発されているため、インストール時に PHP ソース コードと一緒にコンパイルする必要があります。つまり、PHP コアにコンパイルされるため、パフォーマンスの点で優れています。同時に、高い同時実行性の処理においても spawn-fcgi よりも優れており、少なくとも fastcgi プロセッサを自動的に再起動しません。したがって、PHP を解析するには、Nginx PHP/PHP-FPM の組み合わせを使用することをお勧めします。Spawn-FCGI と比較すると、PHP-FPM は CPU とメモリの制御が優れており、前者は簡単にクラッシュして crontab で監視する必要がありますが、PHP-FPM にはそのような問題はありません。
FastCGI の主な利点は、動的言語を HTTP サーバーから分離することです。そのため、Nginx と PHP/PHP-FPM は、フロントエンド Nginx サーバーへの負荷を共有し、Nginx が排他的に処理できるようにするために、異なるサーバーにデプロイされることがよくあります。 PHP/PHP-FPM サーバーは PHP 動的リクエストのみを解析します。PHP-FPM は FastCGI を管理するためのマネージャーで、PHP のプラグインとして存在します。 -FPM、古いバージョンの php (php5.3.3 より前) では、PHP-FPM をパッチの形式で PHP にインストールする必要があり、PHP は PHP-FPM バージョンと一致している必要があります。これは必須です)
PHP-FPM これは実際には PHP ソース コードへのパッチであり、FastCGI プロセス管理を PHP パッケージに統合するように設計されています。 PHP ソース コードにパッチを適用する必要があり、PHP をコンパイルしてインストールした後に使用できるようになります。
PHP5.3.3 には php-fpm が統合されており、サードパーティ パッケージではなくなりました。 PHP-FPM は、メモリとプロセスを効果的に制御し、PHP 設定をスムーズにリロードできる、より優れた PHP プロセス管理方法を提供し、spawn-fcgi よりも多くの利点があるため、PHP に正式に含まれています。 PHP-FPM を有効にするには、./configure で –enable-fpm パラメーターを渡します。
Fastcgi は php5.3.5 のコアにすでに組み込まれているため、設定時に --enable-fastcgi を追加する必要はありません。 php5.2などの古いバージョンではこの項目を追加する必要があります。
Nginx と PHP-FPM をインストールすると、設定情報:
PHP-FPM のデフォルト設定 php-fpm.conf:
listen_address 127.0.0.1:9000 #これは、PHP の fastcgi プロセスがリッスンする IP アドレスとポートを表します
start_servers
min_spare_servers
max_spare_servers
PHP を実行するための Nginx 構成: nginx.conf を編集し、以下を追加します。ステートメント:
location ~ \.php$ {
root html;
fastcgi_pass 127.0.0.1:9000; のポートを指定します。 fastcgi プロセスがリッスンし、nginx はここを通じて php と対話します
fastcgi_index Index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME /usr/local/nginx/html$fastcgi_script_name;
}
Nginxlocation ディレクティブを通じて、接尾辞 php を持つすべてのファイルは処理のために 127.0.0.1:9000 に渡されます。ここでの IP アドレスとポートは、IP アドレスとポートです。 FastCGI プロセスによって監視されるポート。
全体的なワークフロー:
1) FastCGI プロセス マネージャー php-fpm はそれ自体を初期化し、メイン プロセス php-fpm を開始し、start_serversCGI 子プロセスを開始します。
メインプロセス php-fpm は主に fastcgi サブプロセスを管理し、ポート 9000 をリッスンします。
fastcgi サブプロセスWeb サーバーからの接続を待機しています。
2) クライアントリクエストが Web サーバー Nginx に到達すると、Nginxは location ディレクティブを使用して、サフィックスとして php を持つすべてのファイルを 127.0.0.1:9000 に渡します。つまり、Nginxは location ディレクティブを使用して、サフィックスとして php を持つすべてのファイルを 127.0.0.1:9000 に渡して処理します。
3) FastCGI プロセス マネージャー PHP-FPM は、子プロセス CGI インタープリターを選択して接続します。 Web サーバーは、CGI 環境変数と標準入力を FastCGI 子プロセスに送信します。
4) FastCGI サブプロセスは処理を完了した後、同じ接続から Web サーバーに標準出力とエラー情報を返します。 FastCGI 子プロセスが接続を閉じると、リクエストが処理されます。
5). 次に、FastCGI 子プロセスは、FastCGI プロセス マネージャー (Web サーバーで実行されている) からの次の接続を待機して処理します。
通常、Web には統一された入口があります。 PHPリクエストは同じファイルに送信し、このファイル内の「REQUEST_URI」を解析することでルーティングを実装します。
Nginx 設定ファイルは多数のブロックに分かれており、外側から内側に共通するのは「http」、「server」、「location」などで、デフォルトの継承関係は外側から内側となっています。つまり、内側のブロックは外側のブロックの値をデフォルト値として自動的に取得します。 ############例えば:######
server { listen 80; server_name foo.com; root /path; location / { index index.html index.htm index.php; if (!-e $request_filename) { rewrite . /index.php last; } } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME /path$fastcgi_script_name; fastcgi_pass 127.0.0.1:9000; fastcgi_index index.php; } }
一旦未来需要加入新的「location」,必然会出现重复定义的「index」指令,这是因为多个「location」是平级的关系,不存在继承,此时应该在「server」里定义「index」,借助继承关系,「index」指令在所有的「location」中都能生效。
接下来看看「if」指令,说它是大家误解最深的Nginx指令毫不为过:
if (!-e $request_filename) {
rewrite . /index.php last;
}
很多人喜欢用「if」指令做一系列的检查,不过这实际上是「try_files」指令的职责:
try_files $uri $uri/ /index.php;
除此以外,初学者往往会认为「if」指令是内核级的指令,但是实际上它是rewrite模块的一部分,加上Nginx配置实际上是声明式的,而非过程式的,所以当其和非rewrite模块的指令混用时,结果可能会非你所愿。
include fastcgi_params;
Nginx有两份fastcgi配置文件,分别是「fastcgi_params」和「fastcgi.conf」,它们没有太大的差异,唯一的区别是后者比前者多了一行「SCRIPT_FILENAME」的定义:
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
注意:$document_root 和 $fastcgi_script_name 之间没有 /。
原本Nginx只有「fastcgi_params」,后来发现很多人在定义「SCRIPT_FILENAME」时使用了硬编码的方式,于是为了规范用法便引入了「fastcgi.conf」。
不过这样的话就产生一个疑问:为什么一定要引入一个新的配置文件,而不是修改旧的配置文件?这是因为「fastcgi_param」指令是数组型的,和普通指令相同的是:内层替换外层;和普通指令不同的是:当在同级多次使用的时候,是新增而不是替换。换句话说,如果在同级定义两次「SCRIPT_FILENAME」,那么它们都会被发送到后端,这可能会导致一些潜在的问题,为了避免此类情况,便引入了一个新的配置文件。
此外,我们还需要考虑一个安全问题:在PHP开启「cgi.fix_pathinfo」的情况下,PHP可能会把错误的文件类型当作PHP文件来解析。如果Nginx和PHP安装在同一台服务器上的话,那么最简单的解决方法是用「try_files」指令做一次过滤:
try_files $uri =404;
依照前面的分析,给出一份改良后的版本,是不是比开始的版本清爽了很多:
server { listen 80; server_name foo.com; root /path; index index.html index.htm index.php; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { try_files $uri =404; include fastcgi.conf; fastcgi_pass 127.0.0.1:9000; } }
1).减小Nginx编译后的文件大小
在编译Nginx时,默认以debug模式进行,而在debug模式下会插入很多跟踪和ASSERT之类的信息,编译完成后,一个Nginx要有好几兆字节。而在编译前取消Nginx的debug模式,编译完成后Nginx只有几百千字节。因此可以在编译之前,修改相关源码,取消debug模式。具体方法如下:
在Nginx源码文件被解压后,找到源码目录下的auto/cc/gcc文件,在其中找到如下几行:
# debug CFLAGS=”$CFLAGS -g”
注释掉或删掉这两行,即可取消debug模式。
2.为特定的CPU指定CPU类型编译优化
在编译Nginx时,默认的GCC编译参数是“-O”,要优化GCC编译,可以使用以下两个参数:
CPU タイプを確認するには、次のコマンドを使用できます:#cat /proc/cpuinfo | grep "モデル名"
TCMalloc の正式名は Thread-Caching Malloc で、以下の 1 つです。 Google によって開発されたオープン ソース ツール google-perftools。標準の glibc ライブラリの Malloc と比較して、TCMalloc ライブラリはメモリ割り当てがはるかに効率的で高速であるため、同時実行性が高い状況でのサーバーのパフォーマンスが大幅に向上し、システムの負荷が軽減されます。以下は、TCMalloc ライブラリのサポートを Nginx に追加する方法を簡単に紹介します。
TCMalloc ライブラリをインストールするには、libunwind (32 ビット オペレーティング システムをインストールする必要はありません) と google-perftools の 2 つのソフトウェア パッケージをインストールする必要があります。libunwind ライブラリは、プログラムの基本的な関数呼び出しチェーンを提供します。 64 ビット CPU およびオペレーティング システムに基づく、および関数呼び出しレジスタ関数。 TCMallocを利用してNginxを最適化する具体的な操作手順を以下に説明します。
1). libunwind ライブラリをインストールします
対応する libunwind バージョンは、http://download.savannah.gnu.org/releases/libunwind からダウンロードできます。ここでは libunwind-0.99-alpha.tar.gz です。インストール手順は次のとおりです。
#tar zxvf libunwind-0.99-alpha.tar.gz
# cd libunwind-0.99-alpha/
#CFLAGS=-fPIC ./configure
# make CFLAGS= -fPIC
#make CFLAGS=-fPIC install
2) http://google-perftools.googlecode から google-perftools
をインストールします。 .com 対応する google-perftools バージョンをダウンロードします。ここでダウンロードしたものは google-perftools-1.8.tar.gz です。インストールプロセスは次のとおりです。
[root@localhost home]#tar zxvf google-perftools-1.8.tar.gz
[root@localhost home]#cd google-perftools-1.8/
[root @localhost google-perftools-1.8]# ./configure
[root@localhost google-perftools-1.8]#make && make install
[root@localhost google-perftools-1.8]#echo "/ usr/
local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
[root@localhost google-perftools-1.8]# ldconfig
この時点では、 google-perftools のインストールが完了しました。
3). Nginx を再コンパイルします
Nginx が google-perftools をサポートするには、インストール プロセス中に「-with-google_perftools_module」オプションを追加する必要があります。 Nginxを再コンパイルします。インストール コードは次のとおりです:
[root@localhostnginx-0.7.65]#./configure \
>--with-google_perftools_module --with-http_stub_status_module --prefix=/opt/nginx
[root@localhost nginx-0.7.65]#make
[root@localhost nginx-0.7.65]#make install
Nginx のインストールはここで完了です。
4). google-perftools のスレッド ディレクトリを追加します
スレッド ディレクトリを作成し、ファイルを /tmp/tcmalloc の下に配置します。操作は次のとおりです。
[root@localhost ホーム]#mkdir /tmp/tcmalloc
[root@localhost ホーム]#chmod 0777 /tmp/tcmalloc
5 Nginx メイン設定ファイルの変更
nginx.conf ファイルを変更し、pid 行の下に次のコードを追加します:
#pid logs/nginx.pid;
google_perftools_profiles /tmp/ tcmalloc;
次に、Nginx を再起動して、google-perftools の読み込みを完了します。
6). 実行ステータスの確認
google-perftools が正常にロードされたことを確認するには、次のコマンドを使用して表示できます:
[root@ localhost home]# lsof -n | grep tcmalloc
nginx 2395 誰も 9w REG 8,8 0 1599440 /tmp/tcmalloc.2395
nginx 2396 誰も 11w REG 8,8 0 1599443 /tmp /tcmalloc.2396
nginx 2397 誰も 13w REG 8,8 0 1599441 /tmp/tcmalloc.2397
nginx 2398 誰も 15w REG 8,8 0 159944 2 /tmp/tcmalloc.2398
理由Nginx 構成ファイルでは、worker_processes の値が 4 に設定されているため、4 つの Nginx スレッドが開かれ、各スレッドにはレコードの行が含まれます。各スレッドファイルの後の数値は起動したNginxのpid値です。
この時点で、TCMalloc を使用して Nginx を最適化する操作は完了です。
カーネル パラメーターの最適化は、主に、Linux システムの Nginx アプリケーションのシステム カーネル パラメーターの最適化です。
参考のために、最適化の例を以下に示します。
net.ipv4.tcp_max_tw_buckets = 6000
net.ipv4.ip_local_port_range = 1024 65000
net.ipv4.tcp_tw_recycle = 1
net.ipv4.tcp_tw_reuse = 1
net.ipv4 .tcp_syncookies = 1
net.core.somaxconn = 262144
net.core.netdev_max_backlog = 262144
net.ipv4.tcp_max_orphans = 262144
net.ipv4.tcp_max_syn_backlog = 262144
net.ipv4 .tcp_synack_retries = 1
net.ipv4.tcp_syn_retries = 1
net.ipv4.tcp_fin_timeout = 1
net.ipv4.tcp_keepalive_time = 30
上記のカーネル パラメータ値を /etc/sysctl.conf ファイルに追加し、次のコマンドを実行して有効にします:
[root@ localhost home]# /sbin/sysctl -p
例のオプションの意味を次に示します。
TCP パラメータ設定:
net .ipv4.tcp_max_tw_buckets:オプションは、timewait の数を設定するために使用されます。デフォルトは 180,000 ですが、ここでは 6000 に設定されています。
net.ipv4.ip_local_port_range:オプションは、システムが開くことを許可されるポート範囲を設定するために使用されます。同時実行性が高い状況では、そうしないと、ポート番号が十分ではなくなります。 NGINX がプロキシとして機能する場合、上流サーバーへの各接続は一時ポートまたは一時ポートを使用します。
net.ipv4.tcp_tw_recycle:オプションは、timewait 高速リサイクルを設定および有効にするために使用されます.
net.ipv4.tcp_tw_reuse:オプションを使用して再利用を設定すると、TIME-WAIT ソケットを新しい TCP 接続に再利用できるようになります。
net.ipv4.tcp_syncookies:オプションは、SYN Cookie のセットアップに使用されます。SYN 待機キューがオーバーフローすると、Cookie の処理が有効になります。
net.ipv4.tcp_max_orphans:オプションは、ユーザー ファイル ハンドルに関連付けられていないシステム内の TCP ソケットの最大数を設定するために使用されます。この数を超えると、孤立した接続はただちにリセットされ、警告メッセージが出力されます。この制限は、単純な DoS 攻撃を防ぐことのみを目的としています。この制限に依存しすぎることはできませんし、人為的にこの値を減らすことさえできません。多くの場合、この値を増やす必要があります。
net.ipv4.tcp_max_syn_backlog:オプションは、クライアント確認情報をまだ受信していない接続リクエストの最大値を記録するために使用されます。このパラメータのデフォルト値は、128MB のメモリを備えたシステムの場合は 1024、メモリが小さいシステムの場合は 128 です。
net.ipv4.tcp_synack_retries パラメータの値により、カーネルが接続を放棄する前に送信される SYN ACK パケットの数が決まります。
net.ipv4.tcp_syn_retries オプションは、カーネルが接続の確立を断念する前に送信される SYN パケットの数を示します。
net.ipv4.tcp_fin_timeout オプションは、ソケットが FIN-WAIT-2 状態に留まる時間を決定します。デフォルト値は 60 秒です。この値を正しく設定することは非常に重要ですが、場合によっては、負荷が軽い Web サーバーでも多数のデッド ソケットが発生し、メモリ オーバーフローの危険性があります。
net.ipv4.tcp_syn_retries オプションは、カーネルが接続の確立を断念する前に送信される SYN パケットの数を示します。
送信者がソケットを閉じるように要求した場合、net.ipv4.tcp_fin_timeout オプションは、ソケットが FIN-WAIT-2 状態に留まる時間を決定します。受信側でエラーが発生し、接続が閉じられなかったり、予期せずクラッシュしたりする可能性があります。
net.ipv4.tcp_fin_timeout のデフォルト値は 60 秒です。負荷が小さい Web サーバーであっても、多数のデッドソケットが原因でメモリ オーバーフローが発生するリスクがあることに注意してください。 FIN-WAIT-2 は、最大 1.5KB のメモリしか消費できないため、FIN-WAIT-1 よりも危険性が低くなりますが、寿命は長くなります。
net.ipv4.tcp_keepalive_time オプションは、キープアライブが有効な場合に TCP がキープアライブ メッセージを送信する頻度を示します。デフォルト値は 2 (単位は時間) です。
#バッファキュー:
##net.core.somaxconn:# デフォルト## オプションの値は 128 です。このパラメータは、システムによって同時に開始される TCP 接続の数を調整するために使用されます。同時リクエストが多い場合、デフォルト値ではリンク タイムアウトや再送信が発生する可能性があります。したがって、同時この値を調整するには、リクエストを組み合わせる必要があります。NGINX が許容できる数値によって決定されます。通常、デフォルト値は低い値ですが、NGINX が接続を非常に速く受信するため許容できます。ただし、Web サイトのトラフィックが多い場合は、この値を増やす必要があります。カーネル ログのエラー メッセージにより、この値が小さすぎることがわかります。エラー メッセージが消えるまで値を増やしてください。
注: この値を 512 より大きく設定した場合は、それに応じて NGINX listen コマンドの backlog パラメーターも変更する必要があります。オプションは、各ネットワーク インターフェイスがカーネルの処理よりも早くパケットを受信していることを示します。キューへの送信が許可されるパケット。
4.PHP-FPM の最適化
1) FastCGI プロセスの数を増やす
PHP FastCGI サブプロセスの数を 100 以上に調整します。 4G メモリの場合、200 が推奨されます。ストレス テストを行って最良の値を取得します。
2) PHP-FPM オープン ファイル記述子の制限を増やす
タグ rlimit_files は、オープン ファイル記述子に対する PHP-FPM の制限を設定するために使用されます。値は 1024 です。このラベルの値は、Linux カーネルで開いているファイルの数に関連付ける必要があります。たとえば、この値を 65 535 に設定するには、Linux コマンド ラインで「ulimit -HSn 65536」を実行する必要があります。
次に、PHP-FPM オープン ファイル記述子の制限を増やします
:##“
.
PHP-FPM を再起動します。
ulimit -n はに調整する必要があります。
以上。このパラメータを調整する方法については、インターネット上のいくつかの記事を参照してください。コマンドラインで ulimit -n65536を実行して変更します。変更できない場合は、/etc/security/limits.conf を設定し、#*hard nofile65536## を追加する必要があります。
# * ソフト nofile65536##3) 適切に増やす
max_requests##子がクローズされる前に処理できるリクエストの数。デフォルト設定は 500 です。
nginx で開くプロセスの数は一般に CPU の総コア数と同じで、通常は 4 個または 8 個のプロセスを開くことができます。
各 nginx プロセスによって消費されるメモリは 10 MB です。
worker_cpu_affinity8 CPU の場合、割り当ては次のようになります。
work_cpu_affinity 00000001 00000010 00000100 00001000 00010000
00100000 01000000 10000000
nginx は次の理由で複数のワーカー プロセスを使用できます:
SMP を使用するため
ワーカーがディスク I/O でブロックした場合のレイテンシを短縮するため
接続数を制限するためselect() /poll() が使用される場合のプロセスごと
epoll を使用します
Nginx は最新の epoll (Linux 2.6 カーネル) と kqueue (freebsd) ネットワーク I/O モデルを使用しますが、Apache は伝統的なセレクトモデルを採用。
多数の接続の読み取りと書き込みを処理するには、Apache で使用される選択ネットワーク I/O モデルは非常に非効率です。高同時実行サーバーでは、ポーリング I/O が最も時間のかかる操作です。現在、Linux は高同時実行に耐えることができます。アクセスされる Squid と Memcached は両方とも epoll ネットワーク I/O モデルを使用します。worker_processes
NGINX ワーカー プロセスの数 (デフォルト値は 1)。ほとんどの場合、CPU コアごとに 1 つのワーカー プロセスを実行するのが最善であり、この命令を自動に設定することをお勧めします。ワーカー プロセスが大量のディスク I/O を実行する必要がある場合など、この値を増やしたい場合があります。worker_connections 65535;
ワーカー プロセスごとに許可される同時接続の最大数 (Maxclient = work_processes * work_connections)
keepalive_timeout 75
# ここで、公式の文に注意する必要があります:パラメーターは互いに異なる場合があります。 Line Keep-Alive:
timeout=time Mozilla と Konqueror を理解します。MSIE 自体は、約 60 秒後に
キープアライブ接続を終了します。
large_client_header_buffers 4 32k
顧客要求ヘッダー バッファ サイズnginx は、デフォルトで client_header_buffer_size バッファーを使用してヘッダー値を読み取ります。ヘッダーが大きすぎる場合は、large_client_header_buffers を使用して読み取ります。 HTTP ヘッダーの設定が小さすぎます /Cookie は 400 エラーを報告します nginx 400 bad request
リクエストがバッファを超えると、HTTP 414 エラー (URI Too Long) を報告します nginx は最長の HTTP ヘッダーを受け入れます。サイズは次のいずれかより大きい必要があります。そうしないと、400 HTTP エラー (不正なリクエスト) が報告されます。
open_file_cache max 102400
· max - 最大値を指定します。キャッシュの数、キャッシュがオーバーフローした場合、最長使用ファイル (LRU) が削除されます
例: open_file_cache max=1000 inactive=20s; open_file_cache_valid 30s; open_file_cache_min_uses 2; open_file_cache_errors on;
open_file_cache_errors構文: open_file_cache_errors on | off デフォルト値: open_file_cache_errors off 使用されるフィールド: http、server、location このディレクティブは、ファイルを検索してキャッシュ エラーをログに記録するかどうかを指定します。
open_file_cache_min_uses
open_file_cache_valid
gzip をオンにする
gzip on;gzip_min_length 1k;
gzip_buffers 4 16k;
gzip_comp_level 2;
gzip_types text/ plain application/x-javascript text/css
application/xml;
gzip_vary on;
キャッシュ静的ファイル:
location ~* ^. \.(swf |gif|png|jpg|js|css)$ {
有効期限が切れます1m;
}
応答バッファ:
proxy_buffer_size 128k;
proxy_buffers 32 128k;
proxy_busy_buffers_size 128k;
Nginx は、対応するサービスをプロキシした後、または構成したアップストリームと場所に基づいて、対応するファイルを取得します。 nginx のメモリまたは一時ファイル ディレクトリに解析すると、nginx が応答します。 proxy_buffers、proxy_buffer_size、proxy_busy_buffers_size が小さすぎる場合、コンテンツは nginx 設定に従って一時ファイルに生成されますが、一時ファイルのサイズにもデフォルト値があります。したがって、これら 4 つの値が小さすぎると、一部のファイルの一部しか読み込まれません。したがって、proxy_buffers と proxy_buffer_size、proxy_busy_buffers_size と proxy_temp_file_write_size は、サーバーの状況に応じて適切に調整する必要があります。特定のパラメータの詳細は次のとおりです:
proxy_buffers 32 128k; バッファ領域を 32 個設定し、それぞれのサイズは 128k です
proxy_buffer_size 128k; 各バッファ領域のサイズは 128k です2 つの値に矛盾があり、特定の有効な値が見つからない場合は、上記の設定と一致させることをお勧めします。
proxy_busy_buffers_size 128k;使用中のバッファ領域のサイズを設定し、クライアントに転送される最大キャッシュを制御します
proxy_temp_file_write_size キャッシュ ファイルのサイズ
各リクエストを記録すると CPU と I/O サイクルが消費されます。この影響を軽減する 1 つの方法は、アクセス ログをバッファリングすることです。 。 NGINX は、ログ レコードごとに個別の書き込み操作を実行するのではなく、バッファリングを使用して一連のログ レコードをバッファリングし、1 回の操作でまとめてファイルに書き込みます。
アクセス ログのキャッシュを有効にするには、access_log ディレクティブのパラメータbuffer=size を使用します。バッファーがサイズ値に達すると、NGINX はバッファーの内容をログに書き込みます。指定した期間後に NGINX がキャッシュに書き込むようにするには、flush=time パラメーターを含めます。両方のパラメータが設定されている場合、NGINX は、次のログ エントリがバッファ値を超えるか、バッファ内のログ エントリが設定された時間値を超えると、エントリをログ ファイルに書き込みます。これは、ワーカー プロセスがログ ファイルを再度開くか終了するときにも記録されます。アクセスログを完全に無効にするには、access_log ディレクティブを off パラメータに設定します。
ユーザーが消費できないように複数の制限を設定できます。リソースが多すぎるため、システムのパフォーマンス、ユーザー エクスペリエンス、セキュリティへの影響を避けることができません。関連するディレクティブは次のとおりです:
limit_conn および limit_conn_zone:NGINX は、単一の IP アドレスからの接続など、顧客の接続数の制限を受け入れます。これらのディレクティブを設定すると、1 人のユーザーが過剰な接続を開いたり、使用できる以上のリソースを消費したりすることがなくなります。
limit_rate:クライアントへの転送の応答速度の制限 (複数の接続を開く各クライアントはより多くの帯域幅を消費します)。この制限を設定すると、システムの過負荷が防止され、すべてのクライアントに対してより均一なサービス品質が保証されます。
limit_req および limit_req_zone:NGINX 処理リクエストのレート制限。limit_rate と同じ機能があります。ユーザー制限リクエスト レートに適切な値を設定して、遅すぎるプログラムがアプリケーション リクエスト (DDoS 攻撃など) を上書きするのを防ぐことで、特にログイン ページのセキュリティを向上できます。
max_conns: 上部のゲーム設定ブロックのサーバー コマンド パラメーター。単一サーバーがアップストリーム サーバー グループで受け入れることができる同時実行の最大数。この制限を使用して、上流サーバーの過負荷を防ぎます。値 0 (デフォルト) を設定すると、制限がないことを意味します。
queue (NGINX Plus):最大 max_cons 制限を超えるリクエストの数をアップストリーム サーバーに保存するためのキューを作成します。このディレクティブは、キューに入れられるリクエストの最大数を設定し、オプションでエラーを返すまでの最大待機時間を設定します (デフォルトは 60 秒)。このディレクティブを省略した場合、リクエストはキューに登録されません。
#ゲートウェイまたはプロキシとして動作しているサーバーが、リクエストを実行しようとしたときに、上流のサーバーから無効な応答を受け取りました。
一般的な理由:1. バックエンド サービスがハングアップした場合、直接 502 (nginx エラー ログ: connect() が失敗しました (111: 接続が拒否されました))
2. バックエンド サービスis restarting
例: バックエンド サービスをオフにし、nginx のバックエンド インターフェイスにリクエストを送信すると、nginx ログに 502 エラーが表示されます。
一般的に、Nginx 502 Bad Gateway は php-fpm.conf の設定に関連しており、Nginx 504 Gateway Time-out は nginx.conf の設定に関連しています
1) 現在の設定を確認してください。 PHP FastCGI プロセス数が十分かどうか:
netstat -anpo | grep "php-cgi" | wc -l
実際に使用される「FastCGI プロセス数」が、デフォルトの「FastCGI プロセスの数」の場合、「FastCGI プロセスの数」が十分ではないため、増やす必要があることを意味します。
2). 一部の PHP プログラムの実行時間は、Nginx の待機時間を超えます。nginx.conf 構成ファイルで FastCGI のタイムアウト時間を適切に増やすことができます。例:
http {
......
fastcgi_connect_timeout 300;
fastcgi_send_timeout 300;
fastcgi_read_timeout 300;
......
}
ゲートウェイまたはプロキシとして機能するサーバーが、リクエスト、上流サーバー (HTTP、FTP、LDAP などの URI によって識別されるサーバー) からタイムリーな応答を受信できませんでした。一般的な理由:このインターフェイスは時間がかかりすぎます。バックエンド サービスはリクエストを受信して実行を開始しますが、設定された時間内に nginx にデータを返すことができません。
バックエンドサーバーの処理能力が高すぎます。リクエストを受信した後、スレッドがビジー状態であるため、リクエストのインターフェースを手配できず、設定された時間に nginx にデータを返すことができませんでしたclient_max_body_size: このディレクティブは、リクエスト ヘッダーの Content-Length フィールドに表示される、許可されるクライアント接続リクエスト エンティティ サイズの最大値を指定します。リクエストが指定された値よりも大きい場合、クライアントは「リクエスト」を受け取ります。エンティティが大きすぎます」 (413) エラー。ブラウザはそれを表示する方法を知らないことに注意してください。このエラー。
post_max_size と Upload_max_filesize
を増やしてください。 3. Ngnix error.log が表示されます:
server_name *.xywy.com ;large_client_header_buffers 4 16k;
location / {
#次の 3 行を追加します
proxy_buffer_size 64k;proxy_buffers 32 32k;proxy_busy_buffers_size 128k;
# proxy_set_header ホスト $host; proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
2) nginx PHPcgi
の場合、エラーはアップストリームにあります: " fastcgi://127.0.0.1:9000」。さらに追加する必要があります:
fastcgi_buffers 4 128k;
server { listen 80;server_name ddd.com;
Index Index.html Index.htm Index.php; 4 128k;proxy_buffer_size 64k;proxy_buffers 8 64k;fastcgi_バッファサイズ128k;
fastcgi_buffers 4 128k;
to
脆弱性の紹介: nginx は、広く使用されている高性能 Web サーバーです。リバース プロキシとしてよく使用されるだけでなく、 PHPはとても上手です。 80sec は、重大なセキュリティ問題があることを発見しました。デフォルトでは、サーバーは PHP のあらゆる種類のファイルを誤って解析する可能性があります。これにより、重大なセキュリティ問題が発生し、悪意のある攻撃者が PHP をサポートする nginx を侵害できるようになります。
脆弱性分析: nginx は、デフォルトで cgi モードで実行される php をサポートします。たとえば、構成ファイルでは、 location ~ .php$ {
は PHP の解析をサポートします。 location がリクエストを選択すると、URI 環境変数が使用されます。バックエンド Fastcgi に渡されるキー変数 SCRIPT_FILENAME は、nginx によって生成された $fastcgi_script_name によって決定されます。分析を通じて、$fastcgi_script_name は URI 環境変数によって直接制御されていることがわかります。ここで問題が発生します。 PATH_INFO の抽出をより適切にサポートするために、PHP 設定オプションに cgi.fix_pathinfo オプションが存在し、その目的は SCRIPT_FILENAME から実際のスクリプト名を抽出することです。そこで、http://www.80sec.com/80sec.jpg があると仮定して、次の方法で
を取得します。場所の指示の後、リクエストは処理のためにバックエンドの fastcgi に渡されます。 nginx は環境変数 SCRIPT_FILENAME を設定します。コンテンツは
http://www.80sec.com/80sec.jpg/80sec にアクセスします。
は URI
/80sec.jpg/80sec.php
/scripts/80sec.jpg/80sec.php
/scripts/80sec.jpgしたがって、この問題は存在しません。
バックエンド fastcgi がこのオプションを受け取ると、fix_pathinfo 構成に基づいて SCRIPT_FILENAME で追加の処理を実行するかどうかを決定します。通常、fix_pathinfo が設定されていない場合、ルーティングの選択に PATH_INFO を使用するアプリケーションに影響を与えるため、このオプションは通常はオンになるように設定されています。このオプションを渡すと、Php は実際のスクリプト ファイル名を検索します。検索方法はファイルが存在するかどうかも確認します。このとき、SCRIPT_FILENAME と PATH_INFO は
/scripts/80sec.jpg に分離されます。
## 最後に、このリクエストで実行する必要があるスクリプトとして /scripts/80sec.jpg を使用すると、攻撃者は nginx に PHP を使用させてあらゆる種類のファイルを解析させることができます。POC: nginx が PHP をサポートしているサイトにアクセスし、robots.txt などのリソース ファイルの後に /80sec.php を追加します。この時点で、次の違いが確認できます:
Visit http://www.80sec.com/robots.txt
HTTP/1.1 200 OK
サーバー: nginx/0.6.32
日付: 2010 年 5 月 20 日(木) 10:05 :30 GMTContent-Type: text/plain
Content-Length: 18
Last-Modified: Thu, 20 May 2010 06:26:34 GMT
キープアライブ: timeout=20
Accept-Range: bytes
http://www.80sec.com/robots.txt/80sec.php
# にアクセスしてください。 #HTTP/1.1 200 OK
サーバー: nginx/0.6.32
日付: Thu, 20 May 2010 10:06:49 GMT
Content-Type: text/html
Transfer-Encoding: chunked
接続: keep-alive
Keep-Alive: timeout=20
X-Powered-By: PHP/5.2.6
変更が示す場合の Content-Typeバックエンドの解析責任が変更されると、サイトが脆弱になる可能性があります。
脆弱性ベンダー: http://www.nginx.org
解決策:
公式に連絡を試みましたが、その前に次の方法で損失を軽減できます。メソッド
cgi.fix_pathinfo を 0
または
if ( $fastcgi_script_name ~ ..*/.*php ) {
return 403;
}
PS: 分析プロセスで協力してくれた laruence Daniel に感謝します
以上が「Xiaobi」は、Nginx のモジュールと動作原理を理解するのに役立ちます。 ! !の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。