1. 程式人生 > >Nginx 正向代理和反向代理

Nginx 正向代理和反向代理

前言

最近在搗騰代理,要做個內網yum源代理,之前沒接觸過代理這些個東西,折騰完記錄一下吧。

一、下載原始碼

目前Nginx一般都是使用原始碼編譯,沒有現成的rpm包。下載網址:http://nginx.org/download/。裡面有各個版本的Nginx,隨便找個版本下載即可,儘量使用新版本,至少bug少一點,功能支援也多一點。

二、編譯

Nginx依賴一些元件,需要提前安裝好,比如pcre和zlib,如果要使用https相關模組,還需要安裝openssl元件。如果是CentOS系統的話,直接用yum命令安裝就好了,方便快捷。

yum install openssl* pcre*
zlib*

依賴元件安裝好後,就可以開始編譯Nginx了。解壓Nginx壓縮包,進入到目錄,執行千篇一律的編譯命令。

./configure
make && make install

如果需要使用ssl模組,在configure時新增ssl模組,

./configure --with-http_ssl_module
make && make install

然後就OK了。
Nginx的預設安裝根目錄是/usr/local/nginx,因此它的命令,配置檔案都在這個目錄。為了方便,可以把Nginx的命令路徑新增到環境變數中,這樣就不要用絕對路徑呼叫命令了。

export PATH=$PATH:/usr/local/nginx/sbin

三、代理

代理一般分為正向代理和反向代理。

正向代理是一個位於客戶端和原始伺服器之間的伺服器,為了從原始伺服器取得內容,客戶端向代理髮送一個請求並指定目標(原始伺服器),然後代理向原始伺服器轉交請求並將獲得的內容返回給客戶端。

反向代理實際執行方式是代理伺服器接受網路上的連線請求。它將請求轉發給內部網路上的伺服器,並將從伺服器上得到的結果返回給網路上請求連線的客戶端,此時代理伺服器對外就表現為一個伺服器。

可以這麼認為,對於正向代理,代理伺服器和客戶端處於同一個區域網內;而反向代理,代理伺服器和源站則處於同一個區域網內。

四、配置正向代理

Nginx的配置檔案為/usr/local/nginx/conf/nginx.conf。一般我們不直接在該檔案裡配置我們的代理,轉而使用include的方式,把我們的配置獨立成另一個配置檔案。

...
http {
    ...

    keepalive_timeout  65;

    include yumproxy.conf;//新增自己的配置檔案
}

這樣我們就可以在yumproxy.conf檔案裡配置我們的代理了。

正向代理的配置很簡單,其實兩個語句就行了。

server {
        resolver 192.168.0.1;
        location / {
                proxy_pass http://$http_host$request_uri;
        }
}

其中,
resolver表示DNS伺服器
location表示匹配使用者訪問的資源,並作進一步轉交和處理,可用正則表示式匹配
proxy_pass表示需要代理的地址
$http_host 表示使用者訪問資源的主機部分
$request_uri 表示使用者訪問資源的URI部分。
如,http://nginx.org/download/nginx-1.6.3.tar.gz,則$http_host=nginx.org,$request_uri=/download/nginx-1.6.3.tar.gz。

可以不設定監聽埠號,nginx預設監聽80埠,除非你要修改監聽埠,可以用listen欄位指定。

可以看出,對於正向代理,只是對使用者的訪問進行一個轉發,不做其他處理。

下面我們實際驗證一下這個正向代理是否有效,找了兩臺虛擬機器,一臺用nginx搭建正向代理,另一臺使用該代理訪問,以百度為例。

先確認nginx服務啟動,用netstat命令檢視監聽埠,
這裡寫圖片描述

接下來使用curl命令設定代理訪問百度首頁。
這裡寫圖片描述
訪問成功。

五、反向代理配置

對於反向代理也很簡單,如下,

server {
        server_name www.baidu.com;
        location / {
                proxy_pass http://www.baidu.com/;
        }
}

其中,server_name欄位用於匹配使用者訪問資源的主機名稱。proxy_pass欄位同樣表示轉交的訪問。

與正向代理不同,反向代理是指定了特定的網址。其實也就是限定了訪問的物件。指定使用者訪問www.baidu.com時,只能去百度。如果你把proxy_pass的網址替換為新浪的,那就會出現使用者明明要訪問百度,卻跑到新浪去了。這就是代理劫持了。另外,server_name可以匹配多個主機名,用空格分開即可,也可以用正則表示式匹配主機名。

但是特別要注意一點,對於沒有匹配到的訪問,nginx會預設走第一條server配置,所以一般我們將第一條server設定為阻止頁面。

我們可以實際驗證一下。先按上述配置反向代理,訪問百度,正常返回,注意百度的ETAG,
這裡寫圖片描述

然後我們再訪問新浪,
這裡寫圖片描述
可以看出,此時雖然我們想訪問的是新浪,但是實際返回的還是百度。下面我們在上面反向代理的基礎上新增一個空的server配置,只返回404錯誤。
這裡寫圖片描述
此時,結果和我們預期的一致了,未匹配的全都走第一條server,返回404,也就控制了那些網站能訪問,哪些不能訪問,但是這明顯不是nginx該考慮的。因為nginx的優勢不在於控制訪問,相比之下,squid的ACL才是更明智的選擇,這就是後話了。

由此,我們可以看出,對於正向代理,Nginx沒法控制使用者訪問的資源,對於所有訪問只管轉發。這對於內網需要管理網路訪問來說肯定是不行的。而對比反向代理,是可以控制使用者訪問的網路資源的。只代理允許訪問的網址,不允許訪問的網址到了代理伺服器也出不去。