Nginx

Nginx

功能說明

1. 反向代理

  • what is it?

    順向代理的對象為使用者端,使用場景像是VPN,而反向代理表示代理的對象為伺服器端,透過這個機制,可以隱藏後端運行服務的伺服器IP,訪問者僅能看到Nginx所屬伺服器的IP,如此一來,能夠有效阻擋一些DDOS攻擊的可能性 (因為攻擊者不知道服務伺服器的真正IP),“Cloudflare” 就是一個提供反向代理服務的企業。

    NSH專案中的架構採用了雙重反向代理的設計,使用者若要存取NSH官網,只能連到Cloudflare的IP,透過Cloudflare反向代理,將請求發送到我的VPS上,VPS上架設的nginx則作為第二層反向代理 (==但在NSH專案中因為提供服務的伺服器與nginx鎖在的伺服器為同一臺,故沒有執行反向裡的功能。==)

2. 流量轉發

  • Nginx在單一伺服器的情況下 ip等同於該伺服器的公共ip 但透過設定流量轉發規則 搭配防火牆 可以作為一個濾網的角色 只有符合規則的port能夠收到封包

    舉例來說,假設我的一個服務跑在:8000上,我可以設定規則,只允許443或是80的流量進來,之後再根據請求的目的地轉送到該服務中。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
  #example 1.
      server{
              listen 443 ssl;
              server_name example.com;

              root /var/www/example_dir;
              index frontend.html index.html;

              ssl_certificate /etc/nginx/ssl/newsbot.pem;
              ssl_certificate_key /etc/nginx/ssl/newsbot.key;

              location / {
              # 嘗試尋找檔案,若找不到則回傳 404
              # 如果你未來改用 React 路由,這裡要改為 /index.html
              try_files /data/ex1.html /data/ex2.html/ =404;
              }

              location /api/ {
                  proxy_pass http://127.0.0.1:8000;
                  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_set_header X-Forwarded-Proto $scheme;

              }
      }

  #example 2.
      server{
              listen 80 default_server;
              listen 443 ssl default_server;

              server_name _;

              ssl_certificate /etc/nginx/ssl/newsbot.pem;
              ssl_certificate_key /etc/nginx/ssl/newsbot.key;

              return 444;

      }

由上方兩個例子來說明,第一個例子,可以看到他只設定監聽https協議 (:443),並且設定了ssl來加解密,所以只要使用者想要存取這個服務,在瀏覽器輸入 ==https://example.com/api/…==,Nginx看到這個請求的網域名,就會知道這個請求是要眨我內部一個跑在:8000的服務上。也因此可以存取到該服務底下的API。另外也設定了一些標頭,讓請求封包傳到該服務時,可以檢視該封包的原始資訊。

例如:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
  proxy_pass http://127.0.0.1:8000; # 表示服務跑在:8000上,請轉送到這邊

  proxy_set_header Host $host; # 設定標頭 Host,可以知道請求的主機名稱

  proxy_set_header X-Real-IP $remote_addr; # 設定 X-Real-IP 可以知道客戶端的IP地址

  proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
  # 設定 X-Forwarded-For 可以知道這個請求的詳細來源(可能前一個端點也是反向代理伺服器,所以出發的主機IP是前前端點,透過這行才看得出來。)

  proxy_set_header X-Forwarded-Proto $scheme;
  # 設定 X-Forwarded-Proto 可以知道是以甚麼協議請求的

3. 放置靜態檔案

  • Nginx同時也能夠存放靜態檔案 因為他的機制可以讓檔案直接從硬碟出來 不經過記憶體直達網卡 透過將檔案放在上面 可以讓加載速度變得更快。

    同上方第一個例子,假設前端檔案叫做 frontend.html,預設會從 root 去查找檔案 root /var/www/example_dir 內,如此一來 Nginx 就能在第一時間至該目錄取得前端檔案並回傳。

    ==try_files==: 這個指令用來嘗試查找文件,當 nginx 處理一個請求時,又在你指定的 root 下找不到文件時,他會根據 try_files 指令的設置來查找文件。 當請求的 url 是 http://example.com 時,nginx 會先在 /var/www/example_dir 下查找文件,如果找不到就會嘗試查找 /data/ex1.html,如果還是找不到就會嘗試查找 /data/ex2.html,如果還是找不到就返回 404 錯誤。

    如果搭配前後端分離的寫法,透過下方的location /api/可以讓後端的網址變為 https://example.com/api/ ,等於前後端共用同一個ip 所以不會有CORS的問題。

4. ssl

Nginx還可以處理ssl的問題 也就是讓瀏覽器與伺服器之間走https確保傳輸安全 然後在nginx跟python之間走http (節省加密解密時間)

5. 限流

還能夠限流 限定某個ip的請求次數

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy