<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                # NGINX 陷阱和常見錯誤 翻譯自:[https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/](https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/) > ### 警告: > **請閱讀下面所有的內容!是所有的!** 不管是新手還是老用戶,都可能會掉到一個陷阱中去。下面我們會列出一些我們經常看到,和經常需要解釋如何解決的問題。在 Freenode 的# NGINX IRC頻道中,我們頻繁的看到這些問題出現。 ### 本指南說 最經常看到的是,有人從一些其他的指南中,嘗試拷貝、粘貼一個配置片段。并不是說其他所有的指南都是錯的,但是里面錯誤的比例很可怕。即使是在 Linode 庫中也有質量較差的信息,一些 NGINX 社區成員曾經徒勞的試圖去糾正。 本指南的文檔,是社區成員所創建和審查,他們直接和所有類型的 NGINX 用戶在一起工作。這個特定的文檔之所以存在,是因為社區成員看到有大量普遍和重復出現的問題。 ### 我的問題沒有被列出來 在這里你沒有看到和你具體問題相關的東西。也許我們并沒有解決你經歷的具體問題。不要只是大概瀏覽下這個網頁,也不要假設你是無意才找到這里的。你找到這里,是因為這里列出了你做錯的一些東西。 在許多問題上,當涉及到支持很多用戶,社區成員不希望去支持破碎的配置。所以在提問求助前,先修復你的配置。通讀這個文檔來修復你的配置,不要只是走馬觀花。 ### chmod 777 **永遠不要** 使用777。這可能是一個漂亮的數字,有時候可以懶惰的解決權限問題,但是它同樣也表示你沒有線索去解決權限問題,你只是在碰運氣。你應該檢查整個路徑的權限,并思考發生了什么事情。 要輕松的顯示一個路徑的所有權限,你可以使用 ~~~ namei -om /path/to/check ~~~ ### 把root放在location區塊內 糟糕的配置: ~~~ server { server_name www.example.com; location / { root /var/www/nginx -default/; # [...] } location /foo { root /var/www/nginx -default/; # [...] } location /bar { root /var/www/nginx -default/; # [...] } } ~~~ 這個是能工作的。把 root 放在 location 區塊里面會工作,但并不是完全有效的。錯就錯在只要你開始增加其他的 location 區塊,就需要給每一個 location 區塊增加一個 root 。如果沒有添加,就會沒有 root 。讓我們看下正確的配置。 推薦的配置: ~~~ server { server_name www.example.com; root /var/www/nginx -default/; location / { # [...] } location /foo { # [...] } location /bar { # [...] } } ~~~ ### 重復的index指令 糟糕的配置: ~~~ http { index index.php index.htm index.html; server { server_name www.example.com; location / { index index.php index.htm index.html; # [...] } } server { server_name example.com; location / { index index.php index.htm index.html; # [...] } location /foo { index index.php; # [...] } } } ~~~ 為什么重復了這么多行不需要的配置呢?簡單的使用“index”指令一次就夠了。只需要把它放到http {}區塊里面,下面的就會繼承這個配置。 推薦的配置: ~~~ http { index index.php index.htm index.html; server { server_name www.example.com; location / { # [...] } } server { server_name example.com; location / { # [...] } location /foo { # [...] } } } ~~~ ### 使用if 這里篇幅有限,只介紹一部分使用 if 指令的陷阱。更多陷阱你應該點擊看看邪惡的 if 指令。我們看下 if 指令的幾個邪惡的用法。 > **注意看這里**: > [邪惡的 if 指令](#) #### 用if判斷Server Name 糟糕的配置: ~~~ server { server_name example.com *.example.com; if ($host ~* ^www\.(.+)) { set $raw_domain $1; rewrite ^/(.*)$ $raw_domain/$1 permanent; } # [...] } } ~~~ 這個配置有三個問題。首先是if的使用, 為啥它這么糟糕呢? 你有閱讀邪惡的if指令嗎?當 NGINX 收到無論來自哪個子域名的何種請求,不管域名是www.example.com還是example.com,這個fi指令**總是**會被執行。 因此 NGINX 會檢查**每個請求**的Host header,這是十分低效的。 你應該避免這種情況,而是使用下面配置里面的兩個server指令。 推薦的配置: ~~~ server { server_name www.example.com; return 301 $scheme://example.com$request_uri; } server { server_name example.com; # [...] } ~~~ 除了增強了配置的可讀性,這種方法還降低了 NGINX 的處理要求;我們擺脫了不必要的if指令;我們用了 $scheme 來表示 URI 中是 http 還是 https 協議,避免了硬編碼。 #### 用if檢查文件是否存在 使用if指令來判斷文件是否存在是很可怕的,如果你在使用新版本的 NGINX ,你應該看看rty_files,這會讓你的生活變得更輕松。 糟糕的配置: ~~~ server { root /var/www/example.com; location / { if (!-f $request_filename) { break; } } } ~~~ 推薦的配置: ~~~ server { root /var/www/example.com; location / { try_files $uri $uri/ /index.html; } } ~~~ 我們不再嘗試使用 if 來判斷$uri是否存在,用 try_files 意味著你可以測試一個序列。如果 $uri 不存在,就會嘗試 $uri/ ,還不存在的話,在嘗試一個回調 location 。 在上面配置的例子里面,如果 $uri 這個文件存在,就正常服務;如果不存在就檢測 $uri/ 這個目錄是否存在;如果不存在就按照 index.html 來處理,你需要保證 index.html 是存在的。try_files的加載是如此簡單。這是另外一個你可以完全的消除 if 指令的實例。 ### 前端控制器模式的web應用 “前端控制器模式”是流行的設計,被用在很多非常流行的PHP軟件包里面。里面的很多示例配置都過于復雜。想要Drupal, Joomla等運行起來,只用這樣做就可以了: ~~~ try_files $uri $uri/ /index.php?q=$uri&$args; ~~~ 注意:你實際使用的軟件包,在參數名字上會有差異。比如: - "q"參數用在Drupal, Joomla, WordPress - "page"用在CMS Made Simple 一些軟件甚至不需要查詢字符串,它們可以從REQUEST_URI中讀取。比如WordPress就支持這樣的配置: ~~~ try_files $uri $uri/ /index.php; ~~~ 當然在你的開發中可能會有變化,你可能需要基于你的需要設置更復雜的配置。但是對于一個基礎的網站來說,這個配置可以工作的很完美。你應該永遠從簡單開始來搭建你的系統。 如果你不關心目錄是否存在這個檢測的話,你也可以決定忽略這個目錄的檢測,去掉 “$uri/” 這個配置。 ### 把不可控制的請求發給PHP 很多網絡上面推薦的和PHP相關的 NGINX 配置,都是把每一個.php結尾的 URI 傳遞給 PHP 解釋器。請注意,大部分這樣的PHP設置都有嚴重的安全問題,因為它可能允許執行任意第三方代碼。 有問題的配置通常如下: ~~~ location ~* \.php$ { fastcgi_pass backend; # [...] } ~~~ 在這里,每一個.php結尾的請求,都會傳遞給 FastCGI 的后臺處理程序。這樣做的問題是,當完整的路徑未能指向文件系統里面一個確切的文件時,默認的PHP配置試圖是猜測你想執行的是哪個文件。 舉個例子,如果一個請求中的/forum/avatar/1232.jpg/file.php文件不存在,但是/forum/avatar/1232.jpg存在,那么PHP解釋器就會取而代之,使用/forum/avatar/1232.jpg來解釋。如果這里面嵌入了 PHP 代碼,這段代碼就會被執行起來。 有幾個避免這種情況的選擇: - 在php.ini中設置cgi.fix_pathinfo=0。這會讓 PHP 解釋器只嘗試給定的文件路徑,如果沒有找到這個文件就停止處理。 - 確保 NGINX 只傳遞指定的PHP文件去執行 ~~~ location ~* (file_a|file_b|file_c)\.php$ { fastcgi_pass backend; # [...] } ~~~ - 對于任何用戶可以上傳的目錄,特別的關閉 PHP 文件的執行權限 ~~~ location /uploaddir { location ~ \.php$ {return 403;} # [...] } ~~~ - 使用 *try_files* 指令過濾出文件不存在的情況 ~~~ location ~* \.php$ { try_files $uri =404; fastcgi_pass backend; # [...] } ~~~ - 使用嵌套的 location 過濾出文件不存在的情況 ~~~ location ~* \.php$ { location ~ \..*/.*\.php$ {return 404;} fastcgi_pass backend; # [...] } ~~~ ### 腳本文件名里面的FastCGI路徑 很多外部指南喜歡依賴絕對路徑來獲取你的信息。這在 PHP 的配置塊里面很常見。當你從倉庫安裝 NGINX ,通常都是以在配置里面折騰好“include fastcgi_params;”來收尾。這個配置文件位于你的 NGINX 根目錄下,通常在/etc/nginx/里面。 推薦的配置: ~~~ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; ~~~ 糟糕的配置: ~~~ fastcgi_param SCRIPT_FILENAME /var/www/yoursite.com/$fastcgi_script_name; ~~~ $document_root$ 在哪里設置呢?它是 server 塊里面的 root 指令來設置的。你的 root 指令不在 server 塊內?請看前面關于 root 指令的陷阱。 ### 費力的rewrites 不要知難而退, rewrite 很容易和正則表達式混為一談。實際上, rewrite 是很容易的,我們應該努力去保持它們的整潔。很簡單,不添加冗余代碼就行了。 糟糕的配置: ~~~ rewrite ^/(.*)$ http://example.com/$1 permanent; ~~~ 好點兒的配置: ~~~ rewrite ^ http://example.com$request_uri? permanent; ~~~ 更好的配置: ~~~ return 301 http://example.com$request_uri; ~~~ 反復對比下這幾個配置。第一個 rewrite 捕獲不包含第一個斜杠的完整 URI 。使用內置的變量 $request_uri ,我們可以有效的完全避免任何捕獲和匹配。 ### 忽略 http:// 的rewrite 這個非常簡單, rewrites 是用相對路徑的,除非你告訴 NGINX 不是相對路徑。生成絕對路徑的 rewrite 也很簡單,加上 scheme 就行了。 糟糕的配置: ~~~ rewrite ^ example.com permanent; ~~~ 推薦的配置: ~~~ rewrite ^ http://example.com permanent; ~~~ 你可以看到我們做的只是在 rewrite 里面增加了 *http://*。這個很簡單而且有效。 ### 代理所有東西 糟糕的配置: ~~~ server { server_name _; root /var/www/site; location / { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } } ~~~ 這個是令人討厭的配置,你把 **所有東西** 都丟給了 PHP 。為什么呢? Apache 可能要這樣子做,但在 NGINX 里你不必這樣。換個思路,try_files 有一個神奇之處,它是按照特定順序去嘗試文件的。這意味著 NGINX 可以先嘗試下靜態文件,如果沒有才繼續往后走。這樣PHP就不用參與到這個處理中,會快很多。特別是如果你提供一個1MB圖片數千次請求的服務,通過PHP處理還是直接返回靜態文件呢?讓我們看下怎么做到吧。 推薦的配置: ~~~ server { server_name _; root /var/www/site; location / { try_files $uri $uri/ @proxy; } location @proxy { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } } ~~~ 另外一個推薦的配置: ~~~ server { server_name _; root /var/www/site; location / { try_files $uri $uri/ /index.php; } location ~ \.php$ { include fastcgi_params; fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name; fastcgi_pass unix:/tmp/phpcgi.socket; } } ~~~ 這個很容易,不是嗎?你看,如果請求的 URI 存在, NGINX 會處理掉;如果不存在,檢查下目錄是不是存在,是的話也可以被 NGINX 處理;只有在 NGINX 不能直接處理請求的URI的時候,才會進入 proxy 這個 location 來處理。 現在,考慮下你的請求中有多少靜態內容,比如圖片、css、javascript等。這可能會幫你節省很多開銷。 ### 配置的修改沒有起效 瀏覽器緩存。你的配置可能是對的,但怎么嘗試結果總是不對,百思不得其解。罪魁禍首是你的瀏覽器緩存。當你下載東西的時候,瀏覽器做了緩存。 怎么修復: - 在 Firefox 里面 Ctrl+Shift+Delete ,檢查緩存,點擊立即清理。可以用你喜歡的搜索引擎找到其他瀏覽器清理緩存的方法。每次更改配置后,都需要清理下緩存(除非你知道這個不必要),這會省很多事兒。 - 使用 curl 。 ### VirtualBox 如果你在 VirtualBox 的虛擬機中運行 NGINX ,而它不工作,可能是因為 sendfile() 引起的麻煩。只用簡單的注釋掉 sendfile 指令,或者設置為 off。 該指令大都會寫在 NGINX .conf 文件中: ~~~ sendfile off; ~~~ ### 丟失(消失)的 HTTP 頭 如果你沒有明確的設置 underscores_in_headers on; , NGINX 將會自動丟棄帶有下劃線的 HTTP 頭(根據 HTTP 標準,這樣做是完全正當的). 這樣做是為了防止頭信息映射到 CGI 變量時產生歧義,因為破折號和下劃線都會被映射為下劃線。 ### 沒有使用標準的 Document Root Location 在所有的文件系統中,一些目錄永遠也不應該被用做數據的托管。這些目錄包括 / 和 /root 。你永遠不應該使用這些目錄作為你的 document root。 使用這些目錄的話,等于打開了潘多拉魔盒,請求會超出你的預期獲取到隱私的數據。 **永遠也不要這樣做!!!** ( 對,我們還是要看下飛蛾撲火的配置長什么樣子) ~~~ server { root /; location / { try_files /web/$uri $uri @php; } location @php { [...] } } ~~~ 當一個對 /foo 的請求,會傳遞給 PHP 處理,因為文件沒有找到。這可能沒有問題,直到遇到 /etc/passwd 這個請求。沒錯,你剛才給了我們這臺服務器的所有用戶列表。在某些情況下, NGINX 的 workers 甚至是 root 用戶運行的。那么,我們現在有你的用戶列表,以及密碼哈希值,我們也知道哈希的方法。這臺服務器已經變成我們的肉雞了。 Filesystem Hierarchy Standard (FHS) 定義了數據應該如何存在。你一定要去閱讀下。 簡單點兒說,你應該把 web 的內容**放在 /var/www/ , /srv 或者 /usr/share/www 里面**。 ### 使用默認的 Document Root 在 Ubuntu、 Debian 等操作系統中, NGINX 會被封裝成一個易于安裝的包, 里面通常會提供一個 『默認』的配置文件作為范例,也通常包含一個 document root 來保存基礎的 HTML 文件。 大部分這些打包系統,并沒有檢查默認的 document root 里面的文件是否修改或者存在。 在包升級的時候,可能會導致代碼失效。有經驗的系統管理員都知道,不要假設默認的 document root 里面的數據在升級的時候會原封不動。 你不應該使用默認的 document root 做網站的任何關鍵文件的目錄。 并沒有默認的 document root 目錄會保持不變這樣的約定,你網站的關鍵數據, 很可能在更新和升級系統提供的 NGINX 包時丟失。 ### 使用主機名來解析地址 糟糕的配置: ~~~ upstream { server http://someserver; } server { listen myhostname:80; # [...] } ~~~ 你不應該在 listen 指令里面使用使用主機名。雖然這樣可能是有效的,但它會帶來層出不窮的問題。其中一個問題是,這個主機名在啟動時或者服務重啟中不能解析。這會導致 NGINX 不能綁定所需的 TCP socket 而啟動失敗。 一個更安全的做法是使用主機名對應 IP 地址,而不是主機名。這可以防止 NGINX 去查找 IP 地址,也去掉了去內部、外部解析程序的依賴。 例子中的 upstream location 也有同樣的問題,雖然有時候在 upstream 里面不可避免要使用到主機名,但這是一個不好的實踐,需要仔細考慮以防出現問題。 推薦的配置: ~~~ upstream { server http://10.48.41.12; } server { listen 127.0.0.16:80; # [...] } ~~~ ### 在 HTTPS 中使用 SSLv3 由于 SSLv3 的 [POODLE 漏洞](https://www.openssl.org/~bodo/ssl-poodle.pdf),建議不要在開啟 SSL 的網站使用 SSLv3。你可以簡單粗暴的直接禁止 SSLv3, 用 TLS 來替代: ~~~ ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看