Nginx反向代理

  • 關於反向代理

    Nginx能夠作爲一個反向代理來終結來自客戶端的請求,並且向上遊服務器打開一個新連接。新連接代表客戶端向上遊服務器發送請求。代理到上游服務器的配置中,最重要的是proxy_pass指令。該指令有一個參數,URL請求將會被轉換,帶有URI部分的proxy_pass指令將會使用該URI代替客戶端request_uri部分。

location /uri {
    proxy_pass http://localhost:8080/newuri;
}


    實例:

[root@master vhost]# cat proxy.conf
server {
    listen 80;
    server_name localhost.myserver.com;
    access_log /usr/local/nginx/logs/proxy_access.log normal;
    location /test {
        proxy_pass http://localhost:8080/index;
    }
}
[root@master vhost]# cat localhost_myserver_com.conf
server {
    listen 8080;
    server_name localhost.myserver.com;
    access_log /usr/local/nginx/logs/localhost_access.log normal;
    location / {
        root /usr/local/nginx/html;
    }
}

    此時,在localhost_access.log中記錄的請求發生了改變:

[root@master logs]# tail -1 proxy_access.log
192.168.1.38 - - 2019-03-28T04:02:58-04:00 "GET http://localhost.myserver.com/test.html HTTP/1.1"200 249 393 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36""-" 0.001 0.001
[root@master logs]#
[root@master logs]# tail -1 localhost_access.log
127.0.0.1 - - 2019-03-28T04:02:58-04:00 "GET http://localhost.myserver.com/index.html HTTP/1.0"200 205 414 "-" "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.96 Safari/537.36""-" 0.001 -

    這個規則有兩個例外情況:

        如果location定義了一個正則表達式,或者在location中有rewrite規則改變了URI時,在proxy_pass指定URI部分是不被允許的。



  • 向上遊服務器傳遞客戶端真實IP

location / {
    proxy_set_header Host $host;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://192.168.1.202:8080;
    }



  • upstream模塊

    upstream模塊經常與proxy搭配使用。upstream模塊啓用新的配置區段,定義了一組上游服務器。這些服務器可能被設置了不同的權重(權重越高的服務器將被Nginx分配更多的連接),也可能是不同的類型(TCP或UNIX域),也可能出於對服務器的維護而標記爲down。

 

  使用指定的負載均衡算法

    Nginx默認會採用輪詢算法,如果想切換爲ip_hash或least_conn,只需要在upstream開始位置指定負載均衡算法

upstream nginxservers {
    least_conn;
    server 192.168.1.201:8080;
    server 192.168.1.202:8080;
    keepalive 32;
}

    向上遊服務器保持活動連接

    Nginx服務器將會爲每一個worker進程保持同上遊服務器的連接。在Nginx需要同上遊服務器持續保持一定數量的打開連接時,連接緩存非常有用。Nginx將會使用HTTP/1.1協議的持久連接機制維護這些打開的連接。

    在下面的例子中,Nginx起初僅需要爲每一個worker進程打開32個TCP連接,然後通過不發送close的Connection頭保持這些連接。

    使用proxy_http_version指定使用HTTP/1.1協議同上遊服務器進行通信。

    使用proxy_set_header指令清除了Connection頭的內容。

    在業務高峯期,Nginx會打開超過32個TCP連接,當高峯期結束,Nginx將關閉最近最少使用的連接,使連接數回落到32。

upstream nginxservers {
    server 192.168.1.201:8080;
    server 192.168.1.202:8080;
    keepalive 32;
}
server {
    listen 80;
    server_name localhost.myserver.com;
    access_log /usr/local/nginx/logs/proxy_access.log normal;
    location / {
        proxy_http_version 1.1;
        proxy_set_header Connection "";
        proxy_pass http://nginxservers;
    }
}


    使用Memcached作爲上游服務器

upstream memcaches {
    server 192.168.1.201:11211;
    server 192.168.1.202:11211;
}
server {
    location / {
        set $memcached_key "$uri?$args";
        memcached_pass memcaches;
        error_page 404 = @appserver;
    }
    location @appserver {
        proxy_pass http://127.0.0.1:8080;
    }
}


    使用FastCGI作爲上游服務器

upstream fastcgis {
    server 192.168.1.201:9000;
    server 192.168.1.202:9000;
}
server {
    location / {
        fastcgi_pass fastcgis;
    }
}

    Nginx通過uwsgi模塊提供基於Python的上游服務器的連接,配置類似於FastCGI模塊,使用uwsgi_pass指令指定上游服務器。



  • 使用錯誤文件處理上游服務器問題

    有一些上游服務器無法響應請求的情況,此時,可以讓Nginx從本地返回一個文件。

server {
    listen 80;
    server_name localhost.myserver.com;
    access_log /usr/local/nginx/logs/proxy_access.log normal;
    location / {
        proxy_pass http://nginxservers;
        error_page 500 502 503 504 /50x.html;
        location = /50x.html {
            root /usr/local/nginx/html;
        }
    }
}

   或者在上游服務器無法響應請求時,想將請求轉發至另一組定義好的後備服務器(fallback)。

server {
    listen 80;
    server_name localhost.myserver.com;
    access_log /usr/local/nginx/logs/proxy_access.log normal;
    location / {
        proxy_pass http://nginxservers;
        error_page 500 502 503 504 = @fallback;
    }
    location @fallback {
        proxy_pass http://localhost:8080;
    }
}



  • 使用SSL對流量進行加密

    使用OpenSSL生成SSL證書

# openssl req -newkey rsa:2048 -nodes -out localhost.myserver.com -keyout localhost.myserver.com.key
    ---- 命令執行時提示輸入公司名、郵件等信息,直接回車即可;
    ---- 完成以上命令會得到證書籤名請求(Certificate Signing Requests),保存在“localhost.myserver.com”文件中;
    ---- 證書籤名由證書頒發機構授予。或者也可以自己簽名,自己的簽名不能用在公網服務器上
# openssl x509 -req -days 365 -in localhost.myserver.com -signkey localhost.myserver.com.key -out localhost.myserver.com.pem
Signature ok
subject=/C=XX/L=Default City/O=Default Company Ltd
Getting Private key


    對客戶端和反向代理之間的流量進行加密

server {
    listen 443 default ssl;
    server_name localhost.myserver.com;
    ssl_prefer_server_ciphers on;
    ssl_protocols SSLv2 SSLv3 TLSv1;
    ssl_ciphers AESGCM:ALL:!DH:!EXPORT:!RC4:+HIGH:!MEDIUM:!LOW:!aNULL:!eNULL;
    ssl_session_timeout 5m;
    ssl_session_cache shared:WEB:10m;
    ssl_certificate /usr/local/nginx/ssl_key/localhost.myserver.com.pem;
    ssl_certificate_key /usr/local/nginx/ssl_key/localhost.myserver.com.key;
    location / {
        access_log /usr/local/nginx/logs/ssl.log normal;
        proxy_set_header X-Forwarded-For-Proto $scheme;
        proxy_pass http://127.0.0.1:8080;
    }
}

    首先使用listen指令的ssl參數激活了SSL模塊。

    然後指定了希望客戶端使用服務器密碼,以及協議類型和使用的認證方法;

    ssl_session_cache指令被設定爲shared,第二部分和第三部分分別是緩存的名稱和大小;

    然後指明證書和key的路徑,要保證文件能被Nginx使用的用戶訪問。

    最後設置X-Forwarded-For-Proto頭的值爲$scheme,告訴上游服務器原始請求使用的是http還是https。


    對反向代理和上游服務器之間的流量進行加密

server {
    ……
    location / {
        ……
        proxy_pass https://127.0.0.1:8080;
    }
}

    要保證上游服務器也啓用了SSL模塊,這裏的上游服務器使用Nginx提供服務,設置方法同“對客戶端和反向代理之間的流量進行加密”。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章