# Web Server - Book mode: https://hackmd.io/@ncnu-opensource/book [toc] :::info ## 什麼是 Server? - 提出要求的時候,以任何形式提供回應的,就可以稱為 Service - 用來提供這些 Service 的軟體、電腦,就可以稱為 **Server** - 種類有很多 - database server、file server、file server、FTP server、DNS server、**Web Server**… - Server 的功能很多,有些我們每天都會使用 - DNS server - 可以透過紀錄 Domain Name ,讓我們不用記一串 IP 也能連到網站 ::: ## 什麼是 Web Server ? - 提供 Web 相關服務的 Server - 希望網頁可以被世界各地任何連上網路的人在瀏覽器上讀出來 >在電腦主機上執行 Web server,它可以幫主機開一個 80 port (預設),此時別人就能透過該電腦主機的 IP 與它建立連線。 > ![](https://hackmd.io/_uploads/S1ThC1iWp.png) > [資料來源](https://medium.com/@justinlee_78563/%E9%97%9C%E6%96%BCweb%E5%BE%8C%E7%AB%AF-1-%E4%BB%80%E9%BA%BC%E6%98%AFweb-server-83ee32bc7d3e) - 存放網路伺服器軟體、還有網站檔案的主機 - HTML 、CSS 、JavaScript 、圖片、影片 > ![](https://hackmd.io/_uploads/SyNijZKW6.png) > Client-Server 架構 > [資料來源](https://vicxu.medium.com/web-server-and-application-server-5a6d9c940eff) <!-- ## Client-Server 架構 ![](https://hackmd.io/_uploads/r1IV4bKbp.png) - 主從式架構 - Client - 主動 - 瀏覽器(Chrome, Firefox) - 要求網路服務的電腦 - Server - 被動 - 提供與管理資源的電腦 - 資源都存在 Server 上 #### 優點 - 資源集中式管理 - Client 端可以直接用現成的瀏覽器 #### 缺點 - 硬體成本高 - 如果伺服器出現問題或超載,那麼所有連接到該伺服器的客戶端都會受到影響 :::info ### P2P (peer-to-peer) 的點對點架構 - 同時扮演著 Client 與 Server - ![](https://hackmd.io/_uploads/SkGgKkjbp.png) - 資料與資源分在整個網路上,沒有集中式資訊儲存系統,也沒有中央服器的維護。每個使用者可以將資料與資源分享出去,提供給其他電腦使用 - 舉個例子來說,假設有ABCD四台主機。各台主機都有互相連線的情況下,A分享了一個檔案上去,經由Hash function產生一組key值,接著B, C, D這三台主機都可以藉由這組key值來取得這份檔案。 - ![](https://hackmd.io/_uploads/rJxW9lK-a.png) > [資料來源](https://medium.com/@justinlee_78563/%E9%97%9C%E6%96%BCweb%E5%BE%8C%E7%AB%AF-1-%E4%BB%80%E9%BA%BC%E6%98%AFweb-server-83ee32bc7d3e) #### 優點 A.分散式系統資源,分散伺服器負擔。 B.並行處理能力佳。 C.系統處理容量遠大於Web-Base的Client-Server架構。 D.使用記憶體管理交換資訊,效能大幅提昇。 E.硬體成本低。 F.客戶端與客戶端採取直接即時的溝通。 #### 缺點 A.架構較複雜,除開發服器端程式外,還要有專用的客戶端程式。 B.客戶端上線後才會有資源分享出,因此如果客戶端少的話,分享資源就少。 ::: --> ## HTTP - 全名是 **H**yper**t**ext **T**ransfer **P**rotocol,中文翻作「 **超文本傳輸協定**」。 - Client 和 Server 就是透過 HTTP 協定進行溝通 - **Application layer** - 預設 port :**80 port** > ![](https://hackmd.io/_uploads/S1R8p-Ybp.png) >通常 Client 端指的是 Browser (瀏覽器) > > [資料來源](https://jimmyswebnote.com/what-is-server/) ## port > SSH 已經有提到 - IP + 數字編號 - `127.0.0.1:80` - 用於區分同一個 IP 地址下的**不同服務** <!-- :::info ## 生活中的例子- 以郵局為例 郵局有多個辦事窗口。每個窗口都對應於特定的服務,如繳費、寄包裹。當你到郵局時,你需要選擇正確的窗口來完成業務。 在網路中,port 的作用就像郵局的窗口,確定了電腦上的特定應用程式或服務。 ::: ### 為什麼需要 port ? 1. 區分不同的服務 - 當封包傳回來,就能根據 port 來判斷這些資料應該傳送到哪個服務 2. 同時運行多個服務 - 由於每個服務都有自己的 port,能夠在同一時間傳送資料,而不會送錯 - 本來要傳給 telegram 的封包,結果被送到 line ### port number - 範圍:從 0 ~ 65535 - 16 bits 表示,共有 65535 個 port (2^16) - ![](https://hackmd.io/_uploads/Sk9PhmAZT.png) #### Well-Known Ports - `0` - 保留 port ,平常不會啟用 - `1 ~ 1023` 需超**級使用者權限**才能占用這些 port - ![](https://hackmd.io/_uploads/BkVeoXC-6.png) > [圖片來源](https://en.wikipedia.org/wiki/Port_(computer_networking)) - 由 IANA 進行管理和分配 #### Registered Ports - `1024 ~ 49151` - 公司或組織可以向IANA申請和註冊這範圍內的 port - 不需超級使用者權限 - 特定的服務 - `MySQL database service (also for MariaDB)` : `3306` #### Private/Dynamic Ports - `49152 ~ 65535` - 網路中的這些 port 未向 IANA 註冊 - 可以在 local 或由應用程式動態使用 :::info ### IANA (Internet Assigned Numbers Authority) - 非營利組織 - 定義 port number - 管理即維護 Domain Names、Number Resources、Protocol Assignments - ![](https://hackmd.io/_uploads/BkCPLLR-a.png) > [網站](https://www.iana.org/) ::: --> ### `/etc/services` > SSH 已經有提到 - 紀錄各式各樣服務會占用的 port - `cat /etc/services` - service name, port number, Protocol, aliases (別名) - ![](https://hackmd.io/_uploads/BkO7evAZp.png) - SMTP service uses TCP on port 25 and also goes by the alias “mail.” - 查看現在開啟的 port - `netstat -atupl` - ![](https://hackmd.io/_uploads/SJ5SoP0ba.png) - `Proto`:封包 or 通訊協定 - `Local Address`:本地端的 IP 與 port ,如果 `/etc/services` 存在對應服務名稱,就以服務名稱顯示 - `Foreign Address` :監聽哪一個 IP 與 port - `state`:狀態列 * `LISTEN` :表示該 port 已經在 監聽 網路服務 * `ESTABLISHED`:已建立連線 * `TIME_WAIT`:該連線目前是等待的狀態,隨時有可能會斷線 :::info ### 參數說明 `-a `:顯示出目前所有的網路連線狀態 `-t` :顯示 tcp 封包 `-u` :顯示 udp 封包 `-p ` :顯示此連線的 PID `-l` :顯示 LISTEN 的內容 `-n ` :預設情況中,顯示出的 host 會以 host name 來顯現,若為 n 則可以使 port 與 host 都以數字顯示 > [資料來源](https://linux.vbird.org/linux_basic/mandrake9/0560daemons.php) > FIXME: `netstat -atupl` & `netstat -tupl` 差異 ::: > 1. 試試 `-n` > 2. 打開 firefox,輸入`netstat -ntupl` > 3. kill pid ## 常見的 Web Server 簡介 - **Lighttpd** (發音為“lighty”) - ![](https://hackmd.io/_uploads/ryEf9xeGp.png) - 占用系統資源少,運作輕量 - 低記憶體佔用、低 CPU 負載、速度最佳化 - 支援 CGI、FastCGI、SCGI,允許使用任何程式語言撰寫 Web 應用程式 - 在提供靜態內容方面高效,但動態內容可能會消耗較多資源 - 靜態內容 : 預先創建的文件,例如 HTML, CSS 和 JavaScript - 動態內容 : 像是 php,需要的 client 傳送才會有內容 - 適合提供**靜態內容** & 系統資源比較受限 - **Apache** - ![](https://hackmd.io/_uploads/S19ype-Mp.png) - 歷史最悠久,曾經擁有最高的市場佔有率,2019 後被 Nginx 超車 - 有許多模組,可擴展性高 - 由於模組功能強大,因此佔用的系統資源較多。 - **Nginx** - ![](https://hackmd.io/_uploads/rJxbTxWzp.png) - 佔有記憶體少、穩定性高,可以同時承受很大的流量 - 採用模組化設計,有大量的模組庫和第三方模組庫可供選擇。 - 設計的目標是為了超越 Apache,並且在 2019 年成功超越 Apache 成為市場佔有率最高的 --- :::danger ### 本次課程安裝順序依照 Lighttpd -> Apache2 -> Nginx ::: :::info ## 操作 Web Server 的指令 - `sudo service <service_name> <<操作>>` - <<操作>> * `status` 查看狀態 * `start` 開啟服務 * `stop` 關閉服務 * `reload` 不停止服務,重載設定檔 * `restart` 停止服務重新開啟 ::: ## Lighttpd 實作 ### 安裝與介紹 - 安裝 - `sudo apt install lighttpd` - 查看狀態 - `sudo service lighttpd status` - ![](https://hackmd.io/_uploads/S1wq1W-za.png) - `sudo service lighttpd stop` - ![](https://hackmd.io/_uploads/Sk42JWWGp.png) - 看一下 run 在哪個 port - `sudo netstat -ntupl` - ![](https://hackmd.io/_uploads/SyUHeb-z6.png) - 至 url 輸入 `http://127.0.0.1:80` - ![](https://hackmd.io/_uploads/HJYFd7bGp.png) - ![](https://hackmd.io/_uploads/B1fKmrZf6.png) - `conf-available` - 放置所有的設定檔 - 是 **可用**,但 **未啟用** - `conf-enabled` - 假如要使用設定檔,需把 `conf-available`中的設定檔,**Soft link** 到`conf-enabled` - 使設定檔 **啟用** - 當 lighttpd 啟動或重新啟動時,它會載入`conf-enabled` 資料夾中的所有配置 :::info ## 啟用 modules ### 1. 使用 Softlink 方式啟用 modules - `sudo ln -s /etc/lighttpd/conf-available/99-unconfigured.conf /etc/lighttpd/conf-enabled/` - **要記得 reload** - ![](https://hackmd.io/_uploads/HJtfgL0MT.png) ### 2. 使用 `lighty-enabled ` & `lighty-disabled` 來啟用和停用 modules - 啟用 - `sudo lighttpd-enable-mod <<modules>>` - 沒有 `數字` &`.conf` - ![](https://hackmd.io/_uploads/S11X6BAz6.png) > 它會提醒要 reload - 停用 - `sudo lighttpd-disable-mod <<modules>>` ::: - 主要設定檔 `lighttpd.conf` - `/etc/lighttpd/lighttpd.conf` - ![](https://hackmd.io/_uploads/SJC9D_9GT.png) > FIXME: 盡量不要去改主檔案 - `server.modules`:預設啟動哪些模組 - `server.document-root`:網頁根目錄位置 - `server.errorlog` - `server.username` & `server.groupname`:指定可以運行伺服器的使用者名稱 - 可以在 `/etc/passwd` 找到 - ![](https://hackmd.io/_uploads/HkgI0nBZM6.png) - 專門給 web server 使用的特定 user/group - 主要希望 web server 不要有太高的權限,但同時讓 web application 適當進行寫入 - `server.port` - `index-file.names`:紀錄有哪些預設的頁面,可以在這自行新增檔案 - `url.access-deny` : 讓使用者無法存取特定檔案 - 在一些 .php 型的網頁中,會用 `.inc` 檔來儲存與 DB 連線的 IP、帳密 - 有人在伺服器上直接改檔案時,會留下有 `~` 符號作為前置/後綴的檔名作為暫存檔 - `static-file.exclude-extensions`: 哪些副檔名的檔案,不能被當作 static file - 當有一些特定模組沒有被啟動或有設定檔設定失誤的時候,所有的檔案,都會被當作 static file - static file : 可被下載的檔案 - .html、.jpg ### Demo #### 新增檔案 - 查看 `server.document-root` 上面寫的路徑為 `/var/www/html` - ![](https://hackmd.io/_uploads/Hy85Y7ZfT.png) ###### 新增一個 `index.html` - `sudo service lighttpd stop` - 至`/var/www/html` 新增 `index.html` ```javascript= <h1>lighttpd </h1> <h2> index.html </h2> ``` - `sudo service lighttpd restart` - `http://127.0.0.1` > 實作完刪掉 `index.html`,不然下載 apache2 會撞到 ###### 新增一個 `test.html` - `sudo service lighttpd stop` - 至`/var/www/html` 新增 `test.html` & 至`index-file.names` 欄位新增 `test.html` ([參考](https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40oJ7l_4AbTkCmGKJnAmApWw%2FSJQq5lSvF#%E5%95%9F%E5%8B%95)) - ![](https://hackmd.io/_uploads/HJKf_d5z6.png) > **發現沒用,至 `conf-enabled` 看設定檔** ```javascript= <h1>lighttpd </h1> <h2> test.html</h2> ``` - ![](https://hackmd.io/_uploads/rkdpSHZGT.png) - `sudo vim /etc/lighttpd/conf-enabled/99-unconfigured.conf` - ![](https://hackmd.io/_uploads/H1jYOE-M6.png) > 新增一個 `test.html` - `:=` :用於重寫或覆蓋之前的配置 - 所以`99-unconfigured.conf`這裡的 `index-file.names` 覆蓋了`/etc/lighttpd/lighttpd.conf` 中的設定 - `/etc/lighttpd/lighttpd.conf` 的`index-file.names`![](https://hackmd.io/_uploads/B1Wwa4bMa.png) :::info ### `+=` : 補充或增加設定內容,不會覆蓋掉原本的 - `sudo vim /etc/lighttpd/lighttpd.conf ` - ![](https://hackmd.io/_uploads/ryAZ_VyXa.png) ::: <!-- > FIXME:補充 lighttpd 的 name-based,`==` `=~`(部分比對) --> - `sudo service lighttpd restart` :::warning 如果想要以 `/etc/lighttpd/lighttpd.conf` 的 `index-file.names` 為主,就把`99-unconfigured.conf` 刪掉,以防止 lighttpd 載入它。 ::: #### 更改 port - `sudo service lighttpd stop` - 至`/etc/lighttpd/lighttpd.conf`更改 `server.port` 修改成 `8080` - ![](https://hackmd.io/_uploads/rkxjY5mbzp.png) - `sudo service lighttpd restart` - 查看現在 port - `sudo netstat -ntupl` - ![](https://hackmd.io/_uploads/SysncmbfT.png) - 至 url 輸入 `http://127.0.0.1:8080` - ![](https://hackmd.io/_uploads/rysfeB-M6.png) ## Apache2 實作 ### 安裝與介紹 - 安裝 - `sudo apt install apache2` - 查看狀態 - `sudo service apache2 status` - ![](https://hackmd.io/_uploads/B1G-u8Wza.png) - 查看 run 在哪個 port - `sudo netstat -ntupl` - `http://127.0.0.1:80` - ![](https://hackmd.io/_uploads/BJg4_IWM6.png) - ![](https://hackmd.io/_uploads/rJoxF8bGp.png) - `apache2.conf`:主設定檔,配置目錄中的其他文件都是從此文件載入的 - ![](https://hackmd.io/_uploads/r1169L-za.png) - `ports.conf` - 再觀察 `apache2.conf` 發現只會載入結尾是`enabled` 的資料夾 - ![](https://hackmd.io/_uploads/r1dHLBffT.png) - ![](https://hackmd.io/_uploads/r1r88rzfa.png) - `sites-available` & `sites-enabled` : virtual host 的設定文件 - ![](https://hackmd.io/_uploads/Bk-2ESGfa.png) - `000-default.conf`:http 的設定檔案 - `default-ssl.conf`:https 的設定檔案 - `mods-available` & `mods-enabled` : 存放模組 - `conf-available` & `conf-enabled` : 與特定模組無關的其他設定檔 ### Demo #### 更改 port 為 8081 - `sudo service apache2 stop` - 修改 `ports.conf` - ![](https://hackmd.io/_uploads/H1oaYUWM6.png) - `sudo service apache2 restart` - ![](https://hackmd.io/_uploads/S13xqLbMT.png) - `http://127.0.0.1:8081` ## Nginx 實作 ### 安裝 - 安裝 - `sudo apt install nginx` - 查看 run 在哪個 port - ![](https://hackmd.io/_uploads/Syr-_DZz6.png) - `http://127.0.0.1:80` - ![](https://hackmd.io/_uploads/SyidtwZz6.png) - ![](https://hackmd.io/_uploads/SyK0vx7fp.png) - `nginx.conf` - `sites-available` - `sites-enabled` ### Demo #### 更改 port 為 8022 - `sudo service nginx stop` - `sudo vim /etc/nginx/sites-avaiable/default` - ![image.png](https://hackmd.io/_uploads/r1GfyJqmT.png) - `sudo service nginx restart` - `sudo netstat -ntupl` ### 介紹 - `nginx.conf` - 主設定檔 - ![](https://hackmd.io/_uploads/B12plPGzT.png) - log 存在哪裡 - ![](https://hackmd.io/_uploads/rkIFeDzz6.png) - Virtual Host 吃了哪些設定檔 - ![](https://hackmd.io/_uploads/SJjRlvMMT.png) - `sites-available` - 設定檔的集中地 - `sites-enabled` - 會被服務運行的設定檔 - ![](https://hackmd.io/_uploads/HkiKzvzz6.png) - ![](https://hackmd.io/_uploads/BkJHvgQza.png) - `root {Path}` - 網頁的根目錄位置 - `index {fileName}` - 當使用者沒有指定要連到這個目錄的哪個檔案時,預設依照順序搜尋檔案 - 順序 : `index.html` -> `index.htm` -> `index.nginx-debian.html` - `server_name {DomainName}` - 根據 Domain Name 選擇正確的 Server 區塊 - 比對 **virtual host** 中有沒有對應的 Server name,如果沒有就會連到 default Server - `server_name _` : **預設**,不符合其他 `server_name` 都會跑來這個區塊 > 下面會有 virtual host 的 demo - `location / {}` - 格式 : `location url {}` - 對特定路徑的操作 - 處理 `/` 的請求 & 所有未被其他 location 區塊匹配的請求 :::info ## 舉例 - 輸入網址 `http://127.0.0.1:8022/ya` - `ya` : 不存在的檔案 - ![image.png](https://hackmd.io/_uploads/ByNwl1qmT.png) ### 步驟 1. **檢查文件** (`$uri`): - 當一個 request 為 `/ya` 時,先檢查是否存在一個名為 `ya` 的文件。如果存在,它就會提供這個文件。 2. **檢查目錄**(`$uri/`): - 若 `ya` 文件不存在,則繼續檢查是否有名為 `ya` 的目錄(即 `/ya/`)。若存在,它會進入此目錄,並至 `index` 欄位中查找指定的檔案。 - ![](https://hackmd.io/_uploads/H1PmVlmf6.png) 3. **回傳 404**: - 如果 `ya` 既不是文件也不是目錄,Nginx 會按照 `try_files` 指令的最後一個參數,回傳一個 `404 Not Found ` --- ### Demo - **location 是可以有很多個的** #### 修改檔案 - `sudo service nginx stop` - 至 `etc/nginx/sites-available/default` 新增一個 location 欄位 ```conf= location /hi { try_files $uri $uri/ =401; } ``` - ![](https://hackmd.io/_uploads/B1CrOSkXp.png) - 至 `var/www/html` 底下新增一個 `hi` 資料夾,並在裡面新增一個 `index.html` ```html= <h1>/var/www/html/hi/index.html</h1> ``` - ` sudo service nginx restart` #### 開網頁測試 ##### 有這個路徑 - `127.0.0.1:8022` - ![image.png](https://hackmd.io/_uploads/HJzZM157a.png) - `127.0.0.1:8022/hi` - ![](https://hackmd.io/_uploads/rJ8OkLkXT.png) - `127.0.0.1:8022/hi/index.html` - ![](https://hackmd.io/_uploads/rJQayIJ7p.png) ##### 沒有這個路徑 - `127.0.0.1:8022/hi/lsagood.html` - ![](https://hackmd.io/_uploads/BkJKe8kXa.png) - `127.0.0.1:8022/lsagood` - ![](https://hackmd.io/_uploads/HkOm-8JQp.png) ::: ## Virtual Host - 允許一台 server 提供多個網站或網頁應用程式,且每個網站可以有自己的 domain name 和網頁內容 - 依據使用者的訊息來提供不同的內容 ### Name-based Virtual Host > FIXME: 補 lighttpd `= ~` - 在同一 server 上架有多個不同網站,不同網站間依據名稱判定 - ![image.png](https://hackmd.io/_uploads/HJ2yhTxXp.png) ### IP-based Virtual Host - 在一台 server 上,開設多個 IP 位址的虛擬主機,可以針對只聽特定的網卡 - ![image](https://hackmd.io/_uploads/B10_rE746.png) ### Port-based Virtual Host - 利用 port 來區別不同的網站 - ![image](https://hackmd.io/_uploads/Sy1xLEXVT.png) ### 以 Name-based Virtual Host 舉例 > **時間有限,看圖片** ![image.png](https://hackmd.io/_uploads/r12a1-cQa.png) - 在 `/etc/nginx/sites-available/default` > 這裡(有精簡過)做示範就好,下面有 Lab 再操作 ```conf= server { listen 8022 default_server; listen [::]:8022 default_server; root /var/www/html; index index.html index.htm index.nginx-debian.html; server_name _; location /hi { try_files $uri $uri/ =401; } location / { try_files $uri $uri/ =404; } } server { listen 8022; listen [::]:8022; server_name lsaexample1.com; root /var/www/example1.com; index index.html; location / { try_files $uri $uri/ =404; } } ``` #### telnet 試試看 - **預設** (default_server) : ```mr= telnet localhost 8022 GET / HTTP/1.1 Host: 127.0.0.1 ``` ![](https://hackmd.io/_uploads/SJ-gQI1XT.png) - **有這個 domain name** : ```mr= telnet localhost 8022 GET / HTTP/1.1 Host: lsaexample1.com ``` ![image.png](https://hackmd.io/_uploads/Bks1bulm6.png) > 當設置 `server_name` 為 `lsaexample1.com`,會根據 url 的 **Host 標頭**來決定導向哪個 server 區塊,就會讀取 `/var/www/example1.com` 底下的 `index.html` - **沒有這個 domain name**,會連到 defualt_server 的 index file ```mr= telnet localhost 8022 GET / HTTP/1.1 Host: lsagood.com ``` ![](https://hackmd.io/_uploads/rkz3QL17T.png) ### Lab ![image.png](https://hackmd.io/_uploads/SyXgFkcQT.png) - `sudo service nginx stop` - 至 `/var/www` 新增一個 `vhost` 資料夾,並在底下新增一個 `index.html` - ![](https://hackmd.io/_uploads/HJW0gzdGT.png) - ![](https://hackmd.io/_uploads/rkikWzOzT.png) - 編輯設定檔 - `sudo vim /etc/nginx/sites-available/nginx-vhost` - 如需更改設定,盡量去客製化的設定檔,而**不要去改主設定檔**,所以才再新增一個 `nginx-vhost`,而不去更動 `default` > 主設定檔是當初安裝軟體所附帶的,隨著版本的更新可能會有新的設定值可以用 or 舊的設定值不能用,只要一旦更改過軟體本身附帶給你的設定檔,下次再更新軟體的時候就不會再更新這個設定檔,所以可能十年後還是這個設定檔,即便新版本附帶很多東西都不會被更新到。 > 所以主設定檔維持乾淨,客製化的東西就另外再新增,也比較可以追蹤我們客製化的東西! [name= BT] - ![](https://hackmd.io/_uploads/HykiDCOzT.png) ```conf= server { listen 8022; server_name vhostnginx; root /var/www/vhost/; location / { try_files $uri $uri/ =404; } } ``` - 將檔案 soft link 至 `sites-enabled` > 可以再次解釋 `available` & `enabled` 的差別 - `sudo ln -s /etc/nginx/sites-available/nginx-vhost /etc/nginx/sites-enabled/` - 查看 `sites-enabled` - ![](https://hackmd.io/_uploads/rkJDOR_zT.png) - 確認 nginx 服務狀態 - `sudo nginx -t` - ![](https://hackmd.io/_uploads/SyqFOCdMT.png) > 如果出問題這裡也會顯示 - 新增一個 DomainName > 為了要連到對的機器(本機) & 我們需要的字串 (`vhostnginx`)來當作 host (`server_name`) > <!-- > 因為想要讓 `vhostnginx` 讓瀏覽器讀的懂,也就是我們輸入 `vhostnginx`還會連到我們的本機,同時因為這個 lab 也需要 `vhostnginx` --> - `sudo vim /etc/hosts` - `127.0.0.1 vhostnginx` - ![](https://hackmd.io/_uploads/HkBN-Mufa.png) > 因為 IP 很難記,所以有了 DomainName 輔助我們,而這個設定檔就是紀錄 DomainName 對應 IP - `sudo service nginx restart` - `http://vhostnginx:8022` - ![](https://hackmd.io/_uploads/rkfUIzuM6.png) - `http://127.0.0.1:8022` - ![image.png](https://hackmd.io/_uploads/ByO8Yyc7a.png) ## Proxy ### Forward Proxy (正向代理) - ![](https://hackmd.io/_uploads/SkOizDKfa.png) - **Server 不知道是哪個 Client 要了資料** > 小明 (client) 因欠銀行錢沒有還,所以沒辦法跟銀行 (server) 貸款,但小明需用錢,於是跟小黃 (proxy) 借了身份來貸款,因此銀行只知道它把錢借給了信用紀錄良好的小黃,而不知道拿到錢的事實上是之前沒還錢的小明 。 - 主要目的 - 節省對外的流量,連外網前會先去 proxy server 查看有沒有資料 - 外網頻寬比內網低,直接連到外網流量會爆掉 > 第一個人先去網站(海底電纜),在一定的時間第二個人要去一樣的網站的話,proxy 就會直接去硬碟找出同樣的網站,就不用再抓一次,可以直接從內網讀取到 ### Reverse Proxy (反向代理) - ![](https://hackmd.io/_uploads/Skjh08FM6.png) - **Client 不知道連到哪一台 Server** > 接待員小白 (reverse proxy) 負責管理客戶的請求。小明(client)來到銀行需要一些服務,透過小白將請求轉發各個窗口(server)。小明只知道是小白在協助他,卻不知道他的請求被送到了A窗口。 - 好處 - 可以有 Load balancing 功能 - Server 的 IP 位址或 port 更改時,只需向 proxy 更改,不需要通知 Client - 可以有 cache #### Reverse Proxy LAB - 用 nginx reverse proxy 到 `apache(8081)` & `https://google.com` - `sudo service nginx stop` - ![image.png](https://hackmd.io/_uploads/ryX-779m6.png) - `sudo vim nginx-proxy` - ![image.png](https://hackmd.io/_uploads/H1Rte7c7T.png) ```conf= server { listen 80; server_name proxynginx; location /proxygoogle/ { proxy_pass https://google.com/; } location /proxyapache2/ { proxy_pass http://127.0.0.1:8081/; } } ``` - 新增主機紀錄 - `sudo vim /etc/hosts` - `127.0.0.1 proxynginx` - `sudo service nginx restart` - `http://proxynginx/proxyapache2/` - `http://proxynginx/proxygoogle/` ::: warning ### 提醒 如果已經更新設定檔,但**重新整理**還是沒有更動,是因為有瀏覽器有 cache,所以把 cache 清掉就沒問題了,或者開**無痕模式**。 #### 以 Firefox 舉例 1. ![](https://hackmd.io/_uploads/SJigBlYz6.png) 2. ![](https://hackmd.io/_uploads/B1yzHlKGa.png) 3. ![](https://hackmd.io/_uploads/ry6fBetM6.png) ::: #### Load Balance Lab (負載平衡) - 將流量合理分配,以提升各個 Server 的資源使用率及可用性 - 避免流量集中給同一台 Server 造成**超載/過載/爆掉**使服務無法正常運行 ##### Lab - `sudo service nginx stop` - 至 `/etc/nginx/sites-available/` 設定相關檔案 - `sudo vim /etc/nginx/sites-available/nginx-lb` - ![](https://hackmd.io/_uploads/SJE_AQqGT.png) ```conf= upstream lsa.lab { server localhost:8080; server tw.search.yahoo.com; } server { listen 8070; server_name lbnginx; location / { proxy_pass http://lsa.lab; } } ``` > 基本上跟設定 Web server 一樣,主要不一樣是 `proxy_pass`,將 Request 導過去在 upstream 所自訂的名稱。 :::info ### upstream - 紀錄要分流的 IP - 後面接的名稱單純變數名稱,隨便命名沒關係 - 預設使用 round-robin 來分配流量 > 其他模式 : > least-connected : 當連線進來時會把 Request 導向連線數較少的 Server > ip-hash:依據 Client IP 來分配到不同台 Server ```conf= upstream lsa.lab { # 預設使用 round-robin # least_conn; # or # ip_hash; server localhost:8080; server tw.search.yahoo.com; } ``` ::: - Soft Link 到 `nginx/sites-enabled/` - `sudo ln -s /etc/nginx/sites-available/nginx-lB /etc/nginx/sites-enabled/` - 新增一個 DomainName - `sudo vim /etc/hosts` - ![](https://hackmd.io/_uploads/BJXftm5Gp.png) - 確認設定檔有沒有問題 - `sudo nginx -t` - 沒有問題就 reload - `sudo service nginx restart` - `sudo service nginx reload` - `http://lbnginx:8070` - 重新整理 `F5` - ![](https://hackmd.io/_uploads/SkYkxV5fT.png) - ![](https://hackmd.io/_uploads/SyVgx49GT.png) :::warning ## 作業 https://hackmd.io/@qtNgFtaqR4Or_CLAuotXjw/S1hiI_XVp ::: ## 參考資料 - https://developer.mozilla.org/zh-TW/docs/Learn/Common_questions/Web_mechanics/What_is_a_web_server - https://webhostinggeeks.com/blog/what-is-lighttpd-web-server-and-how-does-it-work/#:~:text=%E6%80%A7%E5%92%8C%E5%8A%9F%E8%83%BD%E3%80%82-,%E5%A6%82%E4%BD%95%E5%AE%89%E8%A3%9D%20Lighttpd,-Lighttpd%20%E7%9A%84%E5%AE%89%E8%A3%9D - [apache2](https://www.digitalocean.com/community/tutorials/apache-basics-installation-and-configuration-troubleshooting) - https://www.jyt0532.com/2019/11/18/proxy-reverse-proxy/ - https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%40oJ7l_4AbTkCmGKJnAmApWw%2FSJQq5lSvF#Reverse-Proxy - https://hackmd.io/@ncnu-opensource/book/https%3A%2F%2Fhackmd.io%2F%409wMI71WWT7iMKm40e4ZcoA%2FrJbxS-mMj#Lab - https://blog.dtask.idv.tw/Nginx/2018-07-31/