WAF學習之一——Nginx與反向代理

反向代理

https://www.cnblogs.com/loverwangshan/p/9927968.html
https://www.jianshu.com/p/6215e5d24553
流程圖如下:在這裏插入圖片描述

什麼是反向代理

  • 反向代理是(Reverse Proxy)是以代理服務器的形式來接受來自Internet的請求,然後將請求轉發給內部服務器;並從服務器得到響應返回給Internet的客戶端,此時這個代理服務器對外表現和一個服務器是一樣的

  • 比如我想訪問 http://www.test.com/readme,但www.test.com上並不存在readme頁面,於是他是偷偷從另外一臺服務器上取回來,然後作爲自己的內容返回用戶,但用戶並不知情。這裏所提到的 www.test.com 這個域名對應的服務器就設置了反向代理功能。

  • 結論就是,反向代理服務器對於客戶端而言它就像是原始服務器,並且客戶端不需要進行任何特別的設置。客戶端向反向代理的命名空間(name-space)中的內容發送普通請求,接着反向代理服務器將判斷向何處(原始服務器)轉交請求,並將獲得的內容返回給客戶端,就像這些內容原本就是它自己的一樣。

反向代理與正向代理

  • 正向代理(Forward Proxy)通常都被簡稱爲代理,就是在用戶無法正常訪問外部資源,比方說受到GFW的影響無法訪問twitter的時候,我們可以通過代理的方式,讓用戶繞過防火牆,從而連接到目標網絡或者服務。

  • 正向代理的工作原理就像一個跳板,比如:我訪問不了google.com,但是我能訪問一個代理服務器A,A能訪問google.com,於是我先連上代理服務器A,告訴他我需要google.com的內容,A就去取回來,然後返回給我。從網站的角度,只在代理服務器來取內容的時候有一次記錄,有時候並不知道是用戶的請求,也隱藏了用戶的資料,這取決於代理告不告訴網站。

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

  • 在這裏插入圖片描述

  • 在這裏插入圖片描述

工作流程

  • 用戶通過域名發出訪問Web服務器的請求,該域名被DNS服務器解析爲反向代理服務器的IP地址;

  • 反向代理服務器接受用戶的請求;

  • 反向代理服務器在本地緩存中查找請求的內容,找到後直接把內容發送給用戶;

  • 如果本地緩存裏沒有用戶所請求的信息內容,反向代理服務器會代替用戶向源服務器請求同樣的信息內容,並把信息內容發給用戶,如果信息內容是緩存的還會把它保存到緩存中。

優點

  • 普通的代理只能代理內部網絡對於外部Internet網絡的訪問,客戶機需要制定服務器,將發送到web服務器的http請求發送到代理服務器上 . 且不支持外部網絡對於內部網絡的訪問,因爲內部網絡對網部是不可見的.當一個代理服務器能夠代理外部網絡的主機,訪問內部網絡時,就稱他爲反向代理.此時代理服務器對外表現爲一個Web服務器,外部網絡就可以簡單把它當作一個標準的Web服務器而不需要特定的配置。不同之處在於,這個服務器沒有保存任何網頁的真實數據,所有的靜態網頁或者CGI程序,都保存在內部的Web服務器上。因此對反向代理服務器的攻擊並不會使得網頁信息遭到破壞,這樣就增強了Web服務器的安全性。
  • 節約了有限的IP地址,企業內所有的網站共享一個在internet中註冊的IP地址,這些服務器分配私有地址,採用虛擬主機的方式對外提供服務。
  • 減少WEB服務器壓力,提高響應速度:反向代理就是通常所說的web服務器加速,它是一種通過在繁忙的web服務器和外部網絡之間增加一個高速的web緩衝服務器來降低實際的web服務器的負載的一種技術。反向代理是針對web服務器提高加速功能,作爲代理緩存,它並不是針對瀏覽器用戶,而針對一臺或多臺特定的web服務器,它可以代理外部網絡對內部網絡的訪問請求。
    反向代理服務器會強制將外部網絡對要代理的服務器的訪問經過它,這樣反向代理服務器負責接收客戶端的請求,然後到源服務器上獲取內容,把內容返回給用戶,並把內容保存到本地,以便日後再收到同樣的信息請求時,它會把本地緩存裏的內容直接發給用戶,以減少後端web服務器的壓力,提高響應速度。因此Nginx還具有緩存功能。
  • 其他優點
    (1)請求的統一控制,包括設置權限、過濾規則等;
    (2)區分動態和靜態可緩存內容;
    (3)實現負載均衡,內部可以採用多臺服務器來組成服務器集羣,外部還是可以採用一個地址訪問;
    (4)解決Ajax跨域問題;
    (5)作爲真實服務器的緩衝,解決瞬間負載量大的問題;

Nginx模塊

Nginx有五大優點:模塊化、事件驅動、異步、非阻塞、多進程單線程。由內核和模塊組成的,其中內核完成的工作比較簡單,僅僅通過查找配置文件將客戶端請求映射到一個location block,然後又將這個location block中所配置的每個指令將會啓動不同的模塊去完成相應的工作。

模塊劃分

從結構上分爲核心模塊,基礎模塊和第三方快

  • 核心模塊:HTTP模塊、EVENT模塊和MAIL模塊

  • 基礎模塊:HTTP Access模塊、HTTP FastCGI模塊、HTTP Proxy模塊和HTTP Rewrite模塊,

  • 第三方模塊:HTTP Upstream Request Hash模塊、Notice模塊和HTTP Access Key模塊。也可自己添加,如配置Modsecurity模塊
    在這裏插入圖片描述

Nginx的模塊從功能上分爲如下四類:

  • Core(核心模塊):構建nginx基礎服務、管理其他模塊。

  • Handlers(處理器模塊):此類模塊直接處理請求,並進行輸出內容和修改headers信息等操作。

  • Filters (過濾器模塊):此類模塊主要對其他處理器模塊輸出的內容進行修改操作,最後由Nginx輸出。

  • Proxies (代理類模塊):此類模塊是Nginx的HTTP Upstream之類的模塊,這些模塊主要與後端一些服務比如FastCGI等進行交互,實現服務代理和負載均衡等功能

Nginx的核心模塊主要負責建立nginx服務模型、管理網絡層和應用層協議、以及啓動針對特定應用的一系列候選模塊。其他模塊負責分配給web服務器的實際工作:

  • 當Nginx發送文件或者轉發請求到其他服務器,由Handlers(處理模塊)或Proxies(代理類模塊)提供服務;

  • 當需要Nginx把輸出壓縮或者在服務端加一些東西,由Filters(過濾模塊)提供服務。

模塊處理

  • (1)當服務器啓動,每個handlers(處理模塊)都有機會映射到配置文件中定義的特定位置(location);如果有多個handlers(處理模塊)映射到特定位置時,只有一個會“贏”(說明配置文件有衝突項,應該避免發生)。
    處理模塊以三種形式返回:

    • OK
    • ERROR
    • 或者放棄處理這個請求而讓默認處理模塊來處理(主要是用來處理一些靜態文件,事實上如果是位置正確而真實的靜態文件,默認的處理模塊會搶先處理)。
  • (2) 如果handlers(處理模塊)把請求反向代理到後端的服務器,就變成另外一類的模塊:load-balancers(負載均衡模塊)。負載均衡模塊的配置中有一組後端服務器,當一個HTTP請求過來時,它決定哪臺服務器應當獲得這個請求。
    Nginx的負載均衡模塊採用兩種方法:

    • 輪轉法,它處理請求就像紙牌遊戲一樣從頭到尾分發;
    • IP哈希法,在衆多請求的情況下,它確保來自同一個IP的請求會分發到相同的後端服務器。
  • (3) 如果handlers(處理模塊)沒有產生錯誤,filters(過濾模塊)將被調用。多個filters(過濾模塊)能映射到每個位置,所以(比如)每個請求都可以被壓縮成塊。它們的執行順序在編譯時決定。

    • filters(過濾模塊)是經典的“接力鏈表(CHAIN OF RESPONSIBILITY)”模型:一個filters(過濾模塊)被調用,完成其工作,然後調用下一個filters(過濾模塊),直到最後一個filters(過濾模塊)。

      • 過濾模塊鏈的特別之處在於:

        • 每個filters(過濾模塊)不會等上一個filters(過濾模塊)全部完成;

        • 它能把前一個過濾模塊的輸出作爲其處理內容;有點像Unix中的流水線;

    • 過濾模塊能以buffer(緩衝區)爲單位進行操作,這些buffer一般都是一頁(4K)大小,當然你也可以在nginx.conf文件中進行配置。這意味着,比如,模塊可以壓縮來自後端服務器的響應,然後像流一樣的到達客戶端,直到整個響應發送完成。

    • 總之,過濾模塊鏈以流水線的方式高效率地向客戶端發送響應信息。

  • (4) 所以總結下上面的內容,一個典型的HTTP處理週期是這樣的:

客戶端發送HTTP請求 –>

Nginx基於配置文件中的位置選擇一個合適的處理模塊 ->

(如果有)負載均衡模塊選擇一臺後端服務器 –>

處理模塊進行處理並把輸出緩衝放到第一個過濾模塊上 –>

第一個過濾模塊處理後輸出給第二個過濾模塊 –>

然後第二個過濾模塊又到第三個 –>

依此類推 –> 最後把響應發給客戶端。

在這裏插入圖片描述
Nginx本身做的工作實際很少,當它接到一個HTTP請求時,它僅僅是通過查找配置文件將此次請求映射到一個location block,而此location中所配置的各個指令則會啓動不同的模塊去完成工作,因此模塊可以看做Nginx真正的勞動工作者。通常一個location中的指令會涉及一個handler模塊和多個filter模塊(當然,多個location可以複用同一個模塊)。handler模塊負責處理請求,完成響應內容的生成,而filter模塊對響應內容進行處理。

以上內容都是來自如下鏈接,寫的太清晰了,所以全複製了…這篇文章還有很多沒看完,先梳理這些作爲入門…
https://www.jianshu.com/p/6215e5d24553

nginx作爲反向代理的使用

反向代理服務器通常有兩種模型,它可以作爲內容服務器的替身,也可以作爲內容服務器集羣的負載均衡器。

作內容服務器的替身

  • 如果您的內容服務器具有必須保持安全的敏感信息,如信用卡號數據庫,可在防火牆外部設置一個代理服務器作爲內容服務器的替身。當外部客戶機嘗試訪問內容服務器時,會將其送到代理服務器。實際內容位於內容服務器上,在防火牆內部受到安全保護。代理服務器位於防火牆外部,在客戶機看來就像是內容服務器。
  • 當客戶機向站點提出請求時,請求將轉到代理服務器。然後,代理服務器通過防火牆中的特定通路,將客戶機的請求發送到內容服務器。內容服務器再通過該通道將結果回傳給代理服務器。代理服務器將檢索到的信息發送給客戶機,好像代理服務器就是實際的內容服務器。如果內容服務器返回錯誤消息,代理服務器會先行截取該消息並更改標頭中列出的任何 URL,然後再將消息發送給客戶機。如此可防止外部客戶機獲取內部內容服務器的重定向 URL。
  • 這樣,代理服務器就在安全數據庫和可能的惡意攻擊之間提供了又一道屏障。與有權訪問整個數據庫的情況相對比,就算是僥倖攻擊成功,作惡者充其量也僅限於訪問單個事務中所涉及的信息。未經授權的用戶無法訪問到真正的內容服務器,因爲防火牆通路只允許代理服務器有權進行訪問。

作爲內容服務器的負載均衡器

  • 可以在一個組織內使用多個代理服務器來平衡各 Web 服務器間的網絡負載。在此模型中,可以利用代理服務器的高速緩存特性,創建一個用於負載平衡的服務器池。此時,代理服務器可以位於防火牆的任意一側。如果 Web 服務器每天都會接收大量的請求,則可以使用代理服務器分擔 Web 服務器的負載並提高網絡訪問效率。
  • 對於客戶機發往真正服務器的請求,代理服務器起着中間調停者的作用。代理服務器會將所請求的文檔存入高速緩存。如果有不止一個代理服務器,DNS 可以採用“循環複用法”選擇其 IP 地址,隨機地爲請求選擇路由。客戶機每次都使用同一個 URL,但請求所採取的路由每次都可能經過不同的代理服務器。
  • 可以使用多個代理服務器來處理對一個高用量內容服務器的請求,這樣做的好處是內容服務器可以處理更高的負載,並且比其獨自工作時更有效率。在初始啓動期間,代理服務器首次從內容服務器檢索文檔,此後,對內容服務器的請求數會大大下降。

實例

因爲nginx在處理併發方面的優勢,現在這個應用非常常見。當然了Apache的 mod_proxy和mod_cache結合使用也可以實現對多臺app server的反向代理和負載均衡,但是在併發處理方面apache還是沒有nginx擅長。

1)環境:
  • 我們本地是Windows系統,然後使用VirutalBox安裝一個虛擬的Linux系統。在本地的Windows系統上分別安裝nginx(偵聽 8080端口)和apache(偵聽80端口)。在虛擬的Linux系統上安裝apache(偵聽80端口)。這樣我們相當於擁有了1臺nginx在前端 作爲反向代理服務器;後面有2臺apache作爲應用程序服務器(可以看作是小型的server cluster。😉 );
  • nginx用來作爲反向代理服務器,放置到兩臺apache之前,作爲用戶訪問的入口;nginx僅僅處理靜態頁面,動態的頁面(php請求)統統都交付給後臺的兩臺apache來處理。也就是說,可以把我們網站的靜態頁面或者文件放置到nginx的目錄下;動態的頁面和數據庫訪問都保留到後臺的apache服務器上。
  • 如下介紹兩種方法實現server cluster的負載均衡。
  • 我們假設前端nginx(爲127.0.0.1:80)僅僅包含一個靜態頁面index.html;後臺的兩個apache服務器(分別爲localhost:80和158.37.70.143:80),一臺根目錄放置phpMyAdmin文件夾 和test.php(裏面測試代碼爲print "server1";),另一臺根目錄僅僅放置一個test.php(裏面測試代碼爲print "server2";)。
2)針對不同請求的負載均衡:
  • 在最簡單地構建反向代理的時候(nginx僅僅處理靜態不處理動態內容,動態內容交給後臺的apache server來處理),我們具體的設置爲:在nginx.conf中修改: location ~ /.php$ { proxy_pass 158.37.70.143:80 ; }
    • 這樣當客戶端訪問localhost:8080/index.html的時候,前端的nginx會自動進行響應;
    • 當用戶訪問localhost:8080/test.php的時候(這個時候nginx目錄下根本就沒有該文件),但是通過上面的設置 location ~ /.php$(表示正則表達式匹配以.php結尾的文件,詳情參看location是如何定義和匹配的http://wiki.nginx.org /NginxHttpCoreModule) ,nginx服務器會自動pass給158.37.70.143的apache服務器了。該服務器下的test.php就會被自動解析,然後將html的 結果頁面返回給nginx,然後nginx進行顯示(如果nginx使用memcached模塊或者squid還可以支持緩存),輸出結果爲打印 server2。

如上是最爲簡單的使用nginx做爲反向代理服務器的例子;

  • 我們現在對如上例子進行擴展,使其支持如上的兩臺服務器。
  • 我們設置nginx.conf的server模塊部分,將對應部分修改爲:location ^~ /phpMyAdmin/ { proxy_pass 127.0.0.1:80 ; }location ~ /.php$ { proxy_pass 158.37.70.143:80 ; }
    • 上面第一個部分location ^~ /phpMyAdmin/,表示不使用正則表達式匹配(^~),而是直接匹配,也就是如果客戶端訪問的URL是以http://localhost:8080/phpMyAdmin/ 開頭的話(本地的nginx目錄下根本沒有phpMyAdmin目錄),nginx會自動pass到127.0.0.1:80 的Apache服務器,該服務器對phpMyAdmin目錄下的頁面進行解析,然後將結果發送給nginx,後者顯示;
  • 如果客戶端訪問URL是http://localhost/test.php 的話,則會被pass到158.37.70.143:80 的apache進行處理。
  • 因此綜上,我們實現了針對不同請求的負載均衡。
    • 如果用戶訪問靜態頁面index.html,最前端的nginx直接進行響應;
    • 如果用戶訪問test.php頁面的話,158.37.70.143:80 的Apache進行響應;
    • 如果用戶訪問目錄phpMyAdmin下的頁面的話,127.0.0.1:80 的Apache進行響應;
3)訪問同一頁面的負載均衡:
  • 即用戶訪問http://localhost:8080/test.php 這個同一頁面的時候,我們實現兩臺服務器的負載均衡(實際情況中,這兩個服務器上的數據要求同步一致,這裏我們分別定義了打印server1和server2是爲了進行辨認區別)。

  • 現在我們的情況是在windows下nginx是localhost偵聽8080端口;

    • 兩臺apache,一臺是127.0.0.1:80(包含test.php頁面但是打印server1),另一臺是虛擬機的158.37.70.143:80(包含test.php頁面但是打印server2)。
  • 因此重新配置nginx.conf爲:

    • 首先在nginx的配置文件nginx.conf的http模塊中添加,服務器集羣server cluster(我們這裏是兩臺)的定義: upstream myCluster { server 127.0.0.1:80 ; server 158.37.70.143:80 ; }表示這個server cluster包含2臺服務器>然後在server模塊中定義,負載均衡: location ~ /.php$ { proxy_pass http://myCluster ; #這裏的名字和上面的cluster的名字相同proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }這樣的話,如果訪問http://localhost:8080/test.php 頁面的話,nginx目錄下根本沒有該文件,但是它會自動將其pass到myCluster定義的服務區機羣中,分別由127.0.0.1:80;或者 158.37.70.143:80;來做處理。上面在定義upstream的時候每個server之後沒有定義權重,表示兩者均衡;如果希望某個更多響應 的話例如: upstream myCluster { server 127.0.0.1:80 weight=5;server 158.37.70.143:80 ; }這樣表示5/6的機率訪問第一個server,1/6訪問第二個。另外還可以定義max_fails和fail_timeout等參數。
  • 綜上,我們使用nginx的反向代理服務器reverse proxy server的功能,將其佈置到多臺apache server的前端。

  • nginx僅僅用來處理靜態頁面響應和動態請求的代理pass,後臺的apache server作爲app server來對前臺pass過來的動態頁面進行處理並返回給nginx。

  • 通過以上的架構,我們可以實現nginx和多臺apache構成的機羣cluster的負載均衡。兩種均衡:

    • 可以在nginx中定義訪問不同的內容,代理到不同的後臺server;如上例子中的訪問phpMyAdmin目錄代理到第一臺server上;訪問test.php代理到第二臺server上;
    • 可以在nginx中定義訪問同一頁面,均衡(當然如果服務器性能不同可以定義權重來均衡)地代理到不同的後臺server上。如上的例子訪問test.php頁面,會均衡地代理到server1或者server2上。

實際應用中,server1和server2上分別保留相同的app程序和數據,需要考慮兩者的數據同步。

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