天天看點

nginx配置

本文主要是記錄下nginx各種需求的配置,會持續更新。

nginx 配置優先級

  1. 比對到全等比對時,終止後續所有比對,直接傳回;
  2. 步驟一未比對上時,然後周遊所有的普通比對,按照最長比對原則找到最滿足的比對項,如果比對項前面有^~符号,則終止後續正則比對,采用該比對項;反之則繼續後續的正則比對
  3. 步驟一二都未比對上時,此時進行正則比對,找到第一個滿足的正則比對項,直接傳回,若都不滿足,則傳回步驟二中的最長比對項

兩個項目通過同一nginx的相同端口通路

nginx nginx.com.cn 10.100.3.10

server 10.100.3.12

通路url:

https://aaa.test.com

https://bbb.test.com

将以上兩個域名解析到nginx所在server的ip

使用同一個端口時,就按server_name走

server {
            listen              443 ssl;
            server_name         aaa.test.com;
            ssl_certificate     /xx/xxx/server.crt;
            ssl_certificate_key /xx/xxx/server.key;
    
            location / {
                proxy_pass      http://10.100.3.12:8888;
            }
        }
    
    server {
            listen              443 ssl;
            server_name         bbb.test.com;
            ssl_certificate     /xx/xxx/server.crt;
            ssl_certificate_key /xx/xxx/server.key;
    
            location / {
                proxy_pass      http://10.100.3.12:6666;
            }
        }
           

讓http通路跳轉到https

通路http://aaa.test.com跳轉到https://aaa.test.com,即同時支援http與https通路

server {
        listen              80;
        server_name         aaa.test.com;

        if ($scheme = http ) {
        return 301 https://$host$request_uri;
             }
        }
           

使用同一個域名端口代理兩個不同的服務

通過nginx.com.cn:80可以通路到aaa.test.com與bbb.test.com

server {
    listen       80;
    server_name nginx.com.cn;
    index        index.html index.htm index.php;

    location /aaa  {
            proxy_pass https://aaa.test.com/;     
       }
    location /bbb {
            proxy_pass https://bbb.test.com/;
       }
    }
           

以上效果是:

當通路 http://nginx.com.cn/aaa 轉到https://aaa.test.com/

當通路 http://nginx.com.cn/bbb 轉到https://bbb.test.com/

注: proxy_pass那行的最後一個/的作用是:轉發到 https://aaa.test.com/不帶舊的路徑,當沒有這個/,就是http://nginx.com.cn/aaa 轉發到https://aaa.test.com/aaa

nginx配置

多個路由跳轉同一位址

server {
    listen       80;
    listen       443 ssl;
    server_name  m.aaa.com  x.aaa.com;

    ssl_certificate       aaa.com-chain.pem;
    ssl_certificate_key   aaa.com-key.pem;


    location ^~ /dir1 {
        rewrite ^/(.*) https://e.bbb.com$1 redirect;
    }
    location ~^/(dir2/ttt|dir3|dir4|dir5) {
        if ($scheme = http) {
                        rewrite ^(.*)$  https://$host$1 permanent;  
        }
        proxy_pass https://f.bbb.com;
    }


    location /{
        client_body_buffer_size 20M;
        client_max_body_size 20M;
            if ($scheme = http) {
                        rewrite ^(.*)$  https://$host$1 permanent;
        }
        proxy_pass  https://houduanserverzu;
    }
}
           

rewrite與proxy_pass

rewrite 與 proxy_pass雖然最後通路的頁面相同,但是他們通路的方式卻是不一樣的。

rewrite:使用者 http://old.com --> nginx (rewrite http://new.com ) -->傳回new url到使用者 --> 使用者請求http://new.com (現象為使用者搜尋欄的http://old.com變為http://new.com)此為跳轉;

proxy_pass:使用者 http://old.com --> nginx (proxy_pass http://new.com ) --> nginx通路http://new.com 傳回給使用者 (現象為使用者搜尋欄的http://old.com不變)此為代理。

域名跳轉

将域名寫在upstream中,會降域名解析成ip,跳轉到對應的ip,而不是域名

eg:

www.aaa.com 10.2.1.1

upstream  testdomain {
  server  www.aaa.com;
}

server {
       listen              443 ssl;
       server_name         bbb.test.com;
       ssl_certificate     /xx/xxx/server.crt;
       ssl_certificate_key /xx/xxx/server.key;
    
       location / {
           proxy_pass  http://testdomain;
            }
        }
           

此時效果是 http://10.2.1.1

server {
      listen              443 ssl;
      server_name         bbb.test.com;
      ssl_certificate     /xx/xxx/server.crt;
      ssl_certificate_key /xx/xxx/server.key;
    
      location / {
          proxy_pass  http://www.aaa.com;
            }
        }
           

此時效果是 http://www.aaa.com

location =/ 與 location / 優先級不同,引發的通路錯誤問題

我域名www.aaa.com 走代理,在代理伺服器上配置

server {

listen 80;

listen 443 ssl;

server_name www.aaa.com;

ssl_certificate aaa-chain.pem;
ssl_certificate_key aaa-key.pem;

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

location = / {
    if ($scheme = http) {
        rewrite ^(.*)$  https://$host$1 permanent;
    }
    client_body_buffer_size 20M;
    client_max_body_size 20M;
    proxy_pass http://aaa-backend;
}
           

}

http://www.aaa.com/test

後端伺服器接受不到請求,請求通路到代理伺服器的nginx/html下,并未轉到後端代理.

将location =/替換為 location /,通路恢複正常。

請求頭與響應頭

今天的需求是:将某個檔案的 location /test/aaa 的Content-Type配置為json格式"application/json",我做了如下配置一直報錯 502

location /test/aaa {

proxy_set_header Content-Type "application/json";

原因:

請求頭:用戶端/上遊代理 通到伺服器有關于用戶端請求的資訊頭

響應頭:伺服器傳回到浏覽器的資訊頭

proxy_set_header:是Nginx設定請求頭資訊給上遊伺服器

add_header:是Nginx設定響應頭資訊給浏覽器

這裡的Content-Type為響應頭,需要這樣配置:

add_header 'Content-Type' 'application/json';

但是這樣配置會添加一個新的響應頭,不會覆寫之前的nginx.conf裡的 default_type application/octet-stream,那麼如何覆寫呢?

headers-more-nginx-module(ngx_headers_more)子產品:用于添加、設定和清除輸入和輸出的頭資訊
           

nginx -V檢視你的nginx是否安裝此子產品,若沒有,請自行安裝。

覆寫之前的響應頭

location /test/aaa {
    more_set_headers  "Content-Type:application/json";
}
           

注:可能是版本的原因,寫成 more_set_headers "Content-Type" "application/json"; 不生效。

删除之前的響應頭

location /test/aaa {
    more_clear_headers  "Content-Type:application/json";
}
           

還有其他一些用法,大家可自行查閱其他資料

HSTS 強制跳轉請求頭

加上HSTS請求頭,可以實作http強制跳轉https

文法:Strict-Transport-Security: max-age=expireTime [; includeSubDomains] [; preload]

max-age 是必須的參數,它是一個以秒為機關的數值,它代表着HSTS Header的過期時間,一般設定為1年,即 31536000秒。

includeSubDomains 是可選參數,如果設定該參數的話,那麼意味着目前域名及其子域名均開啟HSTS的保護。

preload是可選參數,隻有當你申請将自己的域名加入到浏覽器内置清單的時候才需要使用到它。

eg: add_header Strict-Transport-Security "max-age=31536000; includeSubDomains"