NCNU-OpenSource
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Web Server 筆記統整 [TOC] ## 伺服器 (Server) 概論 ### 什麼是 Server? 在網路中,任何可以對請求提供回應的實體都可以被稱為「服務 (Service)」。提供這些服務的軟體或電腦,則稱為「伺服器 (Server)」。伺服器種類繁多,包括資料庫伺服器 (Database server)、檔案伺服器 (File server)、郵件伺服器 (Email server) 等,而 **Web Server** 便是其中一種。有些伺服器的功能,例如 DNS 伺服器,幾乎每天都會被使用到,它能透過紀錄 Domain Name 讓我們無需記憶複雜的 IP 位址即可連線到網站。 ### 什麼是 Web Server? Web Server 是一種提供網頁相關服務的伺服器。它的主要功能是讓使用者能夠透過瀏覽器,在世界各地任何連上網路的地方顯示自己的網頁內容。 Web Server 存放著網路伺服器軟體以及網站檔案,例如 HTML、CSS、JavaScript、圖片、影片等。當客戶端 (Client),通常是瀏覽器(如 Chrome、Firefox),主動向伺服器發送請求 (request) 時,Web Server 會接收並處理這些請求,然後回傳一個回應 (response) 給客戶端,使客戶端能夠呈現這些資訊。 ![Client-Server 架構圖](https://hackmd.io/_uploads/SygytQ4fkl.png) <p style="text-align: center;">Client-Server 架構</p> Web Server 通常會在主機上開啟一個預設為 80 的 Port,其他電腦即可透過該主機的 IP 和這個 Port 與其建立連線。 ![Web server 開啟 80 Port](https://hackmd.io/_uploads/S1ThC1iWp.png) <p style="text-align: center;">Web Server 開啟 80 Port 示意圖</p> ### HTTP (Hypertext Transfer Protocol) HTTP 的全名是 **H**yper**t**ext **T**ransfer **P**rotocol,中文翻譯為「超文本傳輸協定」。它是一種應用層的協定,定義了客戶端與伺服器之間進行請求和回應的標準。HTTP 的預設 Port 號是 80。 ![HTTP Request/Response 流程](https://i.imgur.com/uoxs9z7.png) <p style="text-align: center;">HTTP Request/Response 流程</p> ### Port (通訊埠) Port 用於區分同一個 IP 地址下的不同服務。每個 Port 提供特定的服務,例如 SSH 使用 22 Port,網頁瀏覽預設使用 80 Port。 **為什麼需要 Port?** 當電腦傳輸和接收來自網路的資料時(例如來自 Chrome、Telegram、遊戲等),電腦需要區分這些混合的資料應該傳送到哪個服務處理。Port 的作用就像郵局的窗口,封包在回傳到電腦時會標記要給哪個 Port,電腦便會將封包分配給目前佔用該 Port 的服務,從而確保資料傳送給正確的應用程式。 **Port 號範圍** Port 號以 16 位元表示,範圍從 0 到 65535。 * **0**:保留 Port,通常不會啟用。 * **1 ~ 1023 (Well-Known Ports)**:這些 Port 需要超級使用者 (root) 權限才能佔用和使用,主要用於一些常見的通訊服務。由 IANA (Internet Assigned Numbers Authority) 進行管理和分配。 ![Well-Known Ports 範例](https://i.imgur.com/gh16rVL.png =550x) <p style="text-align: center;">Well-Known Ports 範例</p> * **1024 ~ 49151 (Registered Ports)**:公司或組織可以向 IANA 申請註冊這些 Port。它們不需要超級使用者權限,用於特定的服務,例如 MySQL 資料庫服務的 3306 Port。 * **49152 ~ 65535 (Private/Dynamic Ports)**:這些 Port 未向 IANA 註冊,可以在本地或由應用程式動態使用。 **`/etc/services` 檔案** `/etc/services` 檔案記錄了各種服務會佔用的 Port 號,包含服務名稱、Port 號、使用的協定以及別名。 ```bash $ cat /etc/services ``` ![/etc/services 內容範例](https://hackmd.io/_uploads/rkdpyH4fJx.png =80%x) <p style="text-align: center;">/etc/services 內容範例</p> **檢查開啟的 Port** 可以使用 `netstat` 指令來查看目前開啟的 Port 和網路連線狀態。 ```bash $ sudo netstat -ntupl ``` * `-a`:顯示出目前所有的網路連線狀態。 * `-t`:顯示 TCP 連線。 * `-u`:顯示 UDP 連線。 * `-p`:顯示此連線的 PID (Process ID) 和程式名稱。若沒有 `sudo` 權限,則無法顯示 PID/Program name。 * `-l`:顯示處於 LISTEN (監聽) 狀態的連線。 * `-n`:以數字顯示 IP 地址和 Port 號,而不是主機名和服務名。 ![netstat -n 與 netstat 差異](https://hackmd.io/_uploads/B1ejs2FzJe.png) <p style="text-align: center;">`netstat -n` 與 `netstat` 差異</p> `Proto` 欄位表示協定類型;`Local Address` 是本地 IP 和 Port,`0.0.0.0` 表示可以接受來自任何地址的請求;`Foreign Address` 是遠端地址和 Port,`0.0.0.0:*` 表示尚未建立具體連線(監聽狀態);`State` 表示連線狀態,`LISTEN` 表示服務正在監聽 Port,`ESTABLISHED` 表示連線已建立。 ## 常見的 Web Server 介紹 目前市場上有許多 Web Server 軟體,雖然它們的功能大同小異,但各有其特性和適合的使用情境。常見的 Web Server 包括 Lighttpd、Apache2 和 Nginx。 | 特性 / 伺服器 | Nginx | Lighttpd | Apache2 | | :------------ | :---------------------------------- | :------------------------------------- | :--------------------------------------- | | **記憶體佔用** | 少 | 少 | 多 | | **穩定性** | 高 | 高 | 中 | | **流量乘載** | 可同時承受很大的流量 (Concurrent connection) | 適合提供靜態內容,動態內容資源消耗較多 | 相對較差,無法同時承受多人連線 | | **速度** | 快 | 最佳化 | 較慢 | | **模組化設計** | 採用模組化設計,有大量的模組和第三方模組 | 支援 CGI、FastCGI、SCGI | 有許多模組,可擴展性高 | | **設定複雜度** | 中等 | 簡單 | 最麻煩,設定複雜 | | **歷史與市佔率** | 設計目標為超越 Apache,2019 年成功超越並成為市場佔有率最高 | "lighty" 輕量級,用於台灣 Ubuntu apt 來源站點 | 歷史最悠久,曾擁有最高市場佔有率,2019 年後被 Nginx 超車 | | **主要用途** | 適合做 Reverse Proxy、Load Balancing | 適合檔案傳輸,靜態內容服務 | 功能多,什麼都支援 | | **優缺點總結** | 佔用記憶體少、穩定性高、速度快,可以同時承受很大流量,適合高併發 | 占用系統資源少,運作輕量,高效處理靜態內容 | 功能強大但占用系統資源多,效率較低,有時伴隨安全性弱點 | ### 操作 Web Server 的指令 對 Web Server 服務進行操作,通常有以下幾種指令格式: * `sudo service <service_name> <操作>` * `sudo systemctl <操作> <service_name>` * `sudo /etc/init.d/<service_name> <操作>` **常用操作**: * `status`:查看服務狀態。 * `start`:開啟服務。 * `stop`:關閉服務。 * `reload`:不停止服務,重載設定檔,使更改生效。 * `restart`:停止服務後重新開啟。 `systemctl` 提供比 `service` 更多的操作指令,例如 `is-failed`、`reload-or-restart` 等。 ## 各 Web Server 實作與配置 ### Lighttpd Lighttpd (發音為 "lighty") 以其佔用系統資源少、運作輕量、低記憶體佔用、低 CPU 負載和速度最佳化而聞名,特別適合提供靜態內容和系統資源有限的環境。 **安裝與狀態** 1. **安裝 Lighttpd** ```bash $ sudo apt install lighttpd ``` 2. **檢查 Lighttpd 狀態** Lighttpd 預設通常會自動開啟。 ```bash $ sudo service lighttpd status ``` ![Lighttpd 服務狀態 (active)](https://hackmd.io/_uploads/S1wq1W-za.png) <p style="text-align: center;">Lighttpd 服務狀態 (active)</p> 若要停止服務: ```bash $ sudo service lighttpd stop ``` ![Lighttpd 服務狀態 (stopped)](https://hackmd.io/_uploads/Sk42JWWGp.png) <p style="text-align: center;">Lighttpd 服務狀態 (stopped)</p> 3. **查看 Lighttpd 運行的 Port** ```bash $ sudo netstat -ntupl | grep lighttpd ``` 預設 Lighttpd 運行在 80 Port。 ![netstat 顯示 Lighttpd 運行在 80 Port](https://hackmd.io/_uploads/SyUHeb-z6.png) <p style="text-align: center;">`netstat` 顯示 Lighttpd 運行在 80 Port</p> 4. **瀏覽器訪問** 在瀏覽器輸入 `http://127.0.0.1:80`,應會看到 Lighttpd 的預設歡迎頁面或佔位頁. ![Lighttpd 預設頁面](https://hackmd.io/_uploads/HJYFd7bGp.png) <p style="text-align: center;">Lighttpd 預設頁面</p> **Lighttpd 設定檔結構** Lighttpd 的主要設定檔為 `/etc/lighttpd/lighttpd.conf`。 * **`conf-available`**:存放所有可用的設定檔,這些設定檔預設為**未啟用**狀態。 * **`conf-enabled`**:存放所有**已啟用**的設定檔。當 Lighttpd 啟動或重啟時,會自動載入此目錄中的設定檔。這些檔案通常是從 `conf-available` 目錄中的檔案建立的軟連結 (Soft Link)。 ![Lighttpd 設定檔資料夾內容](https://hackmd.io/_uploads/H1q2r_sfyg.png) <p style="text-align: center;">Lighttpd 設定檔資料夾內容</p> **Lighttpd 主要設定參數** `lighttpd.conf` 中包含許多重要參數: * `server.modules`:定義預設啟動哪些模組。 ```bash server.modules = ( "mod_indexfile", "mod_access", "mod_alias", "mod_redirect" ) ``` <p style="text-align: center;">Lighttpd `server.modules` 基本設定</p> 可以使用 `server.modules += ("mod_userdir")` 來追加模組,若使用 `=` 則會覆蓋前面的設定。 ![Lighttpd server.modules +=](https://hackmd.io/_uploads/ryAZ_VyXa.png) <p style="text-align: center;">Lighttpd `server.modules +=` 範例</p> * `server.document-root`:指定網站檔案存放的根目錄。 * `server.upload-dirs`:檔案上傳的暫存目錄。 * `server.errorlog`:錯誤日誌的存放位置。 * `server.pid-file`:伺服器程序 ID (PID) 檔案路徑。 * `server.username` & `server.groupname`:指定 Lighttpd 程序運行的使用者和群組身份,通常是 `www-data`。這有助於控制 Web Server 的權限,避免其擁有過高的系統權限。 ![`/etc/passwd` 中 `www-data` 使用者](https://hackmd.io/_uploads/HkgI0nBZM6.png) <p style="text-align: center;">`/etc/passwd` 中 `www-data` 使用者</p> * `server.port`:伺服器監聽的 Port (HTTP 預設是 80)。 * `index-file.names`:定義預設首頁檔案的名稱(如 `index.php`, `index.html`)。當使用者訪問一個目錄而沒有指定具體檔案時,Web Server 會按照此列表的順序尋找並顯示第一個匹配的檔案。 * `url.access-deny`:禁止訪問的檔案類型或模式(如隱藏檔案或設定檔案,例如含有 `~` 或 `.inc` 的檔案)。這可以防止敏感資訊外洩。 * `static-file.exclude-extensions`:排除靜態檔案處理的檔案類型。這些副檔名的檔案,不能被 URL 請求獲取。例如,防止用戶直接下載 `.php` 原始碼。 * `compress.cache-dir`:壓縮檔案的存放位置。 * `compress.filetype`:要壓縮的檔案類型,通常是 Javascript、CSS、HTML。 **更改 Port 為 8080** 1. 停止 Lighttpd 服務。 ```bash $ sudo service lighttpd stop ``` 2. 編輯 Lighttpd 主設定檔 `/etc/lighttpd/lighttpd.conf`,修改 `server.port` 為 `8080`。 ![Lighttpd 更改 Port 為 8080](https://hackmd.io/_uploads/rkxjY5mbzp.png) <p style="text-align: center;">Lighttpd 更改 Port 為 8080</p> 3. 啟動 Lighttpd 服務。 ```bash $ sudo service lighttpd start ``` 4. 檢查 Port 是否已更改。 ```bash $ sudo netstat -ntupl | grep lighttpd ``` ![netstat 顯示 Lighttpd 運行在 8080 Port](https://hackmd.io/_uploads/SysncmbfT.png) <p style="text-align: center;">`netstat` 顯示 Lighttpd 運行在 8080 Port</p> 5. 在瀏覽器輸入 `http://127.0.0.1:8080` 進行測試。 **啟用/停用模組** Lighttpd 提供兩種方式啟用或停用模組: 1. **使用 `lighttpd-enable-mod` 和 `lighttpd-disable-mod` 指令** 這些指令會自動處理設定檔的軟連結。 * 啟用模組 (只需模組名稱,不帶數字和 `.conf` 副檔名): ```bash $ sudo lighttpd-enable-mod <modules_name> ``` ![lighttpd-enable-mod 範例](https://hackmd.io/_uploads/S11X6BAz6.png) <p style="text-align: center;">`lighttpd-enable-mod` 範例</p> ![lighttpd-enable-mod userdir OK 輸出](https://i.imgur.com/zkmDdz1.png) <p style="text-align: center;">`lighttpd-enable-mod userdir` 成功輸出</p> * 停用模組: ```bash $ sudo lighttpd-disable-mod <modules_name> ``` * **重要**:啟用或停用模組後,需要 `sudo service lighttpd force-reload` 或 `sudo service lighttpd restart` 使設定生效。 2. **手動建立/刪除軟連結** 將 `conf-available` 中的設定檔軟連結到 `conf-enabled`。 ```bash $ sudo ln -s /etc/lighttpd/conf-available/10-userdir.conf /etc/lighttpd/conf-enabled/ ``` **Userdir 模組** Userdir 模組允許根據網址後的使用者名稱導向到各自家目錄下的指定資料夾 (通常是 `public_html`)。 * 啟動 `userdir` 模組。 ```bash $ sudo lighttpd-enable-mod userdir ``` * 確認 `userdir.conf` 內容,它會追加 `mod_userdir` 模組,並指定路徑為 `public_html`。 ![Lighttpd userdir 設定檔內容](https://hackmd.io/_uploads/r1V5bCtzJg.png) <p style="text-align: center;">Lighttpd userdir 設定檔內容</p> * 建立 `public_html` 資料夾並給予適當權限。 ```bash $ mkdir ~/public_html $ chmod 755 /home/<username> # 家目錄也需要權限 $ chmod 755 ~/public_html $ vim ~/public_html/index.html ``` * 重啟 Lighttpd。 * 透過 `127.0.0.1:80/~<username>` 訪問。 ### Apache2 Apache 是歷史最悠久的 Web Server,曾經擁有最高的市場佔有率,但在 2019 年後被 Nginx 超越。它有許多模組,可擴展性高,但由於模組功能強大,佔用的系統資源也較多。 **安裝與狀態** 1. **安裝 Apache2** ```bash $ sudo apt install apache2 ``` 2. **檢查 Apache2 狀態** ```bash $ sudo service apache2 status ``` ![Apache2 服務狀態 (active)](https://hackmd.io/_uploads/B1G-u8Wza.png) <p style="text-align: center;">Apache2 服務狀態 (active)</p> 3. **查看 Apache2 運行的 Port** ```bash $ sudo netstat -ntupl | grep apache2 ``` 預設 Apache2 運行在 80 Port。 4. **瀏覽器訪問** 在瀏覽器輸入 `http://127.0.0.1:80`,應會看到 Apache2 Ubuntu Default Page。 ![Apache2 Ubuntu Default Page](https://hackmd.io/_uploads/BJg4_IWM6.png) <p style="text-align: center;">Apache2 Ubuntu Default Page</p> **Apache2 設定檔結構** Apache2 的設定檔結構相對複雜,主要分為多個目錄: * `apache2.conf`:主設定檔,包含 Apache 的全域設定,其他設定檔案都是從此檔案載入的。 * `ports.conf`:定義 Apache 監聽的 Port。 * `conf-available` & `conf-enabled`:存放與特定模組無關的其他功能性設定檔案。 * `mods-available` & `mods-enabled`:存放 Apache 支援的模組相關設定檔案。 * `sites-available` & `sites-enabled`:存放虛擬主機 (Virtual Host) 的設定檔案。 * `000-default.conf`:HTTP 的預設設定檔案。 * `default-ssl.conf`:HTTPS 的預設設定檔案。 ![Apache2 設定檔目錄結構](https://hackmd.io/_uploads/BJgYG8DzJl.png) <p style="text-align: center;">Apache2 設定檔目錄結構</p> **更改 Port 為 8081** 1. 停止 Apache2 服務。 ```bash $ sudo service apache2 stop ``` 2. 編輯 `/etc/apache2/ports.conf` 檔案,將 `Listen 80` 修改為 `Listen 8081`。 ![Apache2 ports.conf 更改 Port 為 8081](https://hackmd.io/_uploads/H1oaYUWM6.png) <p style="text-align: center;">Apache2 `ports.conf` 更改 Port 為 8081</p> 3. 啟動 Apache2 服務。 ```bash $ sudo service apache2 start ``` 4. 檢查 Port 是否已更改。 ```bash $ sudo netstat -ntupl | grep apache2 ``` ![netstat 顯示 Apache2 運行在 8081 Port](https://hackmd.io/_uploads/S13xqLbMT.png) <p style="text-align: center;">`netstat` 顯示 Apache2 運行在 8081 Port</p> 5. 在瀏覽器輸入 `http://127.0.0.1:8081` 進行測試。 ### Nginx Nginx (發音同 "engine X") 設計目標是為了超越 Apache,在 2019 年成功超越 Apache 成為市場佔有率最高的 Web Server。它佔用記憶體少、穩定性高,可以同時承受很大的流量,並採用模組化設計。 **安裝與狀態** 1. **安裝 Nginx** ```bash $ sudo apt install nginx ``` 2. **檢查 Nginx 狀態** ```bash $ sudo service nginx status ``` 3. **查看 Nginx 運行的 Port** ```bash $ sudo netstat -ntupl | grep nginx ``` 預設 Nginx 運行在 80 Port。 ![netstat 顯示 Nginx 運行在 80 Port](https://hackmd.io/_uploads/Syr-_DZz6.png) <p style="text-align: center;">`netstat` 顯示 Nginx 運行在 80 Port</p> 4. **瀏覽器訪問** 在瀏覽器輸入 `http://127.0.0.1:80`,應會看到 "Welcome to nginx!" 頁面。 ![Nginx 預設歡迎頁面](https://hackmd.io/_uploads/SyidtwZz6.png) <p style="text-align: center;">Nginx 預設歡迎頁面</p> **Nginx 設定檔結構** Nginx 的設定檔主要集中在 `/etc/nginx/` 目錄下,並分為三個主要部分,方便管理並避免系統更新時覆蓋使用者自定義設定: * **`nginx.conf`**:主設定檔,包含 Nginx 的全域設定,例如 `worker_processes` (工作程序數量,通常依據 CPU 核心數自動設定)、日誌路徑等。一般情況下不建議直接修改主設定檔,以免影響系統更新。 ![截圖 2025-06-22 下午3.13.36](https://hackmd.io/_uploads/Bku8TQBVgx.png) <p style="text-align: center;">`nginx.conf` `worker_processes` 自動設定</p> ![nginx.conf log 存在哪裡](https://hackmd.io/_uploads/rkIFeDzz6.png) <p style="text-align: center;">`nginx.conf` log 存在哪裡</p> * **`sites-available`**:所有可用的虛擬主機設定檔的集中地,方便管理。這些檔案本身不會生效。 * **`sites-enabled`**:實際讓服務運作的設定檔。此目錄中的檔案是從 `sites-available` 目錄中的檔案軟連結過來的。當 Nginx 啟動或重載時,會載入此目錄中的設定檔。 ![Nginx sites-available 與 sites-enabled 結構](https://hackmd.io/_uploads/HkiKzvzz6.png) <p style="text-align: center;">Nginx `sites-available` 與 `sites-enabled` 結構</p> **Nginx 主要設定參數** 在 Nginx 的 `server` 區塊中,包含以下重要參數: * `listen`:伺服器監聽的 Port (例如 `listen 80;` 或 `listen [::]:80;` 用於 IPv6)。 * `default_server`:當沒有其他 `server_name` 匹配時,會連到此 `server` 區塊。每個 Port 只能有一個 `default_server`。 * `root`:設定網站的根目錄,Nginx 會從這裡提供檔案給訪問者。 * `index`:設定預設首頁檔案的名稱。當用戶訪問目錄時,Nginx 會按順序查找並載入第一個匹配到的檔案(例如 `index.html index.htm index.nginx-debian.html`)。 * `server_name`:根據客戶端請求的 `Host` 標頭 (Domain Name) 選擇正確的 `server` 區塊。`server_name _` 通常表示預設伺服器,不符合其他 `server_name` 的請求會導向這裡。 * `location`:定義對特定路徑或 URL 模式的操作。 * `try_files $uri $uri/ =404;`:Nginx 處理請求的優先順序。例如,當請求 `/asd` 時: 1. **檢查檔案 (`$uri`)**:先檢查 `root` 目錄下是否存在名為 `asd` 的檔案。若存在,則提供該檔案。 2. **檢查目錄 (`$uri/`)**:若 `asd` 檔案不存在,則檢查是否有名為 `asd` 的目錄 (即 `/asd/`)。若存在,則進入此目錄,並依照 `index` 欄位查找指定的檔案。 3. **回傳 404**:如果 `asd` 既不是檔案也不是目錄,Nginx 會回傳 `404 Not Found` 錯誤。 ![Nginx `try_files` 指令流程圖](https://hackmd.io/_uploads/H1PmVlmf6.png) <p style="text-align: center;">Nginx `try_files` 指令流程圖</p> * `location ~ \.php$`:匹配以 `.php` 結尾的路徑,通常會啟動 `fastcgi` 或 `fpm` 等服務來解析和執行 PHP 檔案。 * `location ~ /\.ht`:匹配 `.ht` 開頭的檔案,通常會配置為 `deny all;`,禁止外部訪問,以保護敏感設定檔。 **更改 Port 為 8022** 1. 停止 Nginx 服務。 ```bash $ sudo service nginx stop ``` 2. 編輯 `/etc/nginx/sites-available/default` 檔案,修改 `listen 80` 為 `listen 8022`。 ![Nginx 更改 Port 為 8022](https://hackmd.io/_uploads/r1GfyJqmT.png) <p style="text-align: center;">Nginx 更改 Port 為 8022</p> 3. 重啟 Nginx 服務。 ```bash $ sudo service nginx restart ``` 4. 在瀏覽器輸入 `http://127.0.0.1:8022` 進行測試。 ## 虛擬主機 (Virtual Host) 虛擬主機允許一台伺服器提供多個網站或網頁應用程式,且每個網站可以有自己的 Domain Name 和網頁內容。這樣可以最大化利用伺服器資源,節省硬體成本。伺服器會依據使用者的請求資訊(如 Domain Name, IP, Port)來提供不同的內容。 ### 虛擬主機的類型 1. **基於域名的虛擬主機 (Name-Based Virtual Host)** * 使用不同的 Domain Name 來區分不同的網站。 * 情境:多個網站共享同一個 IP 地址,伺服器根據請求中的 Domain Name (Host 標頭) 來分配請求。 * 範例:`example1.com` 和 `example2.com` 都運行在同一台伺服器上。 ![基於域名的虛擬主機示意圖](https://hackmd.io/_uploads/Sk_6XYwfyx.png) <p style="text-align: center;">基於域名的虛擬主機示意圖</p> 2. **基於 IP 的虛擬主機 (IP-Based Virtual Host)** * 使用不同的 IP 地址來區分網站。 * 情境:每個網站分配一個專屬的 IP 地址。在一台主機上,可以將多個 IP 位址綁定在同一張網卡上,並針對不同 IP 監聽。 ![基於 IP 的虛擬主機示意圖](https://hackmd.io/_uploads/BkaVVKPf1e.png) <p style="text-align: center;">基於 IP 的虛擬主機示意圖</p> 3. **基於 Port 的虛擬主機 (Port-Based Virtual Host)** * 利用 Port 來區別不同的網站。 * 情境:在不使用多個 Domain Name 或 IP 的情況下,運行多個內部應用或 API,或節省 Domain Name 註冊費用。 ![基於 Port 的虛擬主機示意圖](https://hackmd.io/_uploads/Bk8RNYwMJl.png) <p style="text-align: center;">基於 Port 的虛擬主機示意圖</p> ### Nginx Name-Based Virtual Host 實作範例 這個實驗演示如何讓一個 Nginx 伺服器同時為多個 Domain Name 提供服務。 1. **停止 Nginx 服務**。 ```bash $ sudo service nginx stop ``` 2. **建立新的網站根目錄**。 ```bash $ sudo mkdir -p /var/www/vhost/example.com $ sudo vim /var/www/vhost/example.com/index.html ``` `index.html` 內容範例: ```html Welcome to example.com ``` ![建立 `/var/www/vhost` 資料夾及 `index.html`](https://hackmd.io/_uploads/HJW0gzdGT.png) <p style="text-align: center;">建立 `/var/www/vhost` 資料夾及 `index.html`</p> ![`/var/www/vhost/index.html` 內容](https://hackmd.io/_uploads/rkikWzOzT.png) <p style="text-align: center;">`/var/www/vhost/index.html` 內容</p> 3. **新增虛擬主機設定檔**。 建議複製一份預設設定檔作為基礎,然後進行修改。主設定檔不建議直接修改。 ```bash $ sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/nginx-vhost $ sudo vim /etc/nginx/sites-available/nginx-vhost ``` 修改 `nginx-vhost` 內容如下: ```nginx server { listen 8022 default_server; # 預設伺服器,處理所有未匹配的請求 listen [::]:8022 default_server; root /var/www/html; server_name _; location / { try_files $uri $uri/ =404; } location /hi { try_files $uri $uri/ =401; } } server { listen 8022; # 監聽相同的 Port listen [::]:8022; server_name example.com; # 為此虛擬主機設定 Domain Name root /var/www/example.com; # 網站根目錄 index index.html; location / { try_files $uri $uri/ =404; } } ``` <p style="text-align: center;">Nginx 虛擬主機設定範例</p> ![Nginx nginx-vhost 設定範例](https://hackmd.io/_uploads/HykiDCOzT.png) <p style="text-align: center;">Nginx `nginx-vhost` 設定範例</p> 4. **建立軟連結啟用設定檔**。 ```bash $ sudo ln -s /etc/nginx/sites-available/nginx-vhost /etc/nginx/sites-enabled/ ``` ![Nginx 軟連結啟用 sites-enabled](https://hackmd.io/_uploads/rkJDOR_zT.png) <p style="text-align: center;">Nginx 軟連結啟用 `sites-enabled`</p> 5. **新增主機紀錄到 `/etc/hosts`**。 為了讓本機電腦能夠解析 `example.com` 到 `127.0.0.1`。 ```bash $ sudo vim /etc/hosts ``` 新增一行: ``` 127.0.0.1 example.com ``` ![新增主機紀錄 `/etc/hosts`](https://hackmd.io/_uploads/HkBN-Mufa.png) <p style="text-align: center;">新增主機紀錄 `/etc/hosts`</p> 6. **測試 Nginx 設定檔語法**。 ```bash $ sudo nginx -t ``` 如果沒有問題,會顯示 `syntax is ok` 和 `test is successful`。 ![Nginx 設定檔語法測試結果](https://hackmd.io/_uploads/SyqFOCdMT.png) <p style="text-align: center;">Nginx 設定檔語法測試結果</p> 7. **重啟 Nginx 服務**。 ```bash $ sudo service nginx restart ``` 若 `reload` 後沒有改變,可嘗試 `restart`。 8. **使用 `telnet` 或瀏覽器測試**。 * 測試預設伺服器 (default_server): ```bash $ telnet localhost 8022 GET / HTTP/1.1 Host: asdf (亂打一個不存在的 Domain Name) ``` 會回傳預設的網頁 (Nginx 的 default 網頁)。 * 測試 `example.com`: ```bash $ telnet localhost 8022 GET / HTTP/1.1 Host: example.com ``` 會回傳 `Welcome to example.com`。 * 使用瀏覽器訪問 `http://example.com:8022`。 ## 代理 (Proxy) 與負載平衡 (Load Balance) ### 正向代理 (Forward Proxy) * **目的**:位於客戶端和伺服器之間,客戶端透過代理伺服器向外部伺服器發送請求。 * **功能**: * **隱藏客戶端身份**:保護客戶端隱私,外部伺服器只知道代理伺服器的 IP。 * **突破網路限制**:幫助客戶端訪問原本受限制的網站。 * **流量節省與快取**:代理伺服器可以快取經常訪問的內容,減少對外網的頻寬使用。 * **網路存取控制**:機構可以限制內部成員對特定網站的存取。 * **特性**:伺服器只知道代理發出的請求,不知道實際的客戶端是誰。 ![正向代理示意圖](https://hackmd.io/_uploads/BJAWTYDfkl.png) <p style="text-align: center;">正向代理示意圖</p> ### 反向代理 (Reverse Proxy) * **目的**:位於伺服器之前,代表後端伺服器接收客戶端的請求。 * **功能**: * **隱藏後端伺服器**:客戶端不知道真正處理請求的伺服器是哪一台,只與反向代理互動。 * **負載平衡**:將客戶端請求分發到多個後端伺服器,提高資源使用率和可用性。 * **安全性強化**:作為額外的防護層,隱藏內部網路結構。 * **SSL 加密**:可以在代理層處理 SSL 加密/解密,減輕後端伺服器的負擔。 * **快取**:代理伺服器本身可以快取內容,減少對後端伺服器的請求。 * **靈活性**:當後端伺服器的 IP 位址或 Port 更改時,只需向代理伺服器更改設定,無需通知客戶端。 ![反向代理示意圖](https://hackmd.io/_uploads/Sy1mMcvzyl.png =60%x) <p style="text-align: center;">反向代理示意圖</p> **Nginx 反向代理實作範例** 此範例演示如何使用 Nginx 作為反向代理,將請求轉發到 Apache 伺服器 (Port 8081) 或 Google。 1. **停止 Nginx 服務**。 ```bash $ sudo service nginx stop ``` 2. **新增 Nginx 反向代理設定檔**。 ```bash $ sudo vim /etc/nginx/sites-available/nginx-proxy ``` 內容範例: ```nginx server { listen 80; server_name nginxproxy; location /proxygoogle/ { proxy_pass https://google.com/; } location /proxyapache2/ { proxy_pass http://127.0.0.1:8081/; # 轉發到 Apache (假設運行在 8081) } location / { proxy_pass http://127.0.0.1:8080/; # 轉發到 Lighttpd (假設運行在 8080) } } ``` ![Nginx 反向代理設定檔範例](https://hackmd.io/_uploads/H1Rte7c7T.png) <p style="text-align: center;">Nginx 反向代理設定檔範例</p> ![Nginx 反向代理實驗圖](https://hackmd.io/_uploads/ryX-779m6.png =80%x) <p style="text-align: center;">Nginx 反向代理實驗圖</p> 3. **建立軟連結啟用設定檔**。 ```bash $ sudo ln -s /etc/nginx/sites-available/nginx-proxy /etc/nginx/sites-enabled/ ``` 4. **新增主機紀錄到 `/etc/hosts`**。 ```bash $ sudo vim /etc/hosts ``` 新增一行: ``` 127.0.0.1 nginxproxy ``` 5. **重啟 Nginx 服務**。 ```bash $ sudo service nginx restart ``` 6. **在瀏覽器中測試**: * `http://nginxproxy/proxyapache2/` * `http://nginxproxy/proxygoogle/` * `http://nginxproxy/` **注意**:如果更新設定檔後瀏覽器顯示沒有變化,可能是瀏覽器快取問題。可以嘗試清除快取或使用無痕模式。 **Lighttpd 反向代理範例** Lighttpd 也可以實現反向代理。 設定範例(在 `/etc/lighttpd/conf-available/99-lighttpd2-proxy.conf`): ```conf server.modules += ( "mod_proxy" ) $HTTP["host"] == "lighttpd2.proxy.com" { # lighttpd 的 host 匹配不支援底線 proxy.balance = "hash" proxy.server = ( "" => (("Host" => "127.0.0.1", "port" => "8080",))) } ``` <p style="text-align: center;">Lighttpd `proxy.server` 設定範例</p> 啟用後即可將請求轉發給 127.0.0.1:8080 的伺服器。 ### 負載平衡 (Load Balance) 負載平衡是反向代理的一個重要功能,旨在將流量合理分配到多個後端伺服器,以提升各伺服器的資源使用率及可用性。這可以有效避免流量集中在同一台伺服器造成**超載/過載/爆掉**,導致服務無法正常運行,同時也避免伺服器閒置造成的資源浪費。 **Nginx 模擬負載平衡實作範例** 此範例演示如何使用 Nginx 將流量分流到兩個不同的後端,例如本地的 Lighttpd (Port 8080) 和 Yahoo! 搜尋。 1. **停止 Nginx 服務**。 ```bash $ sudo service nginx stop ``` 2. **新增 Nginx 負載平衡設定檔**。 ```bash $ sudo vim /etc/nginx/sites-available/nginx-lb ``` 內容範例: ```nginx upstream lsa.lab { # upstream 定義要分流的 IP 列表 server localhost:8080; # Lighttpd server tw.search.yahoo.com; # Yahoo! # 預設使用 Round-Robin (輪流) 分配流量 # 其他模式如: # least_conn; # 導向連線數較少的 Server # ip_hash; # 依據 Client IP 分配到不同 Server } server { listen 8070; # 監聽 Port server_name lbnginx; # 伺服器名稱 location / { proxy_pass http://lsa.lab; # 將請求轉發給 upstream 定義的組 } } ``` ![Nginx 負載平衡設定檔範例](https://hackmd.io/_uploads/SJE_AQqGT.png) <p style="text-align: center;">Nginx 負載平衡設定檔範例</p> 3. **建立軟連結啟用設定檔**。 ```bash $ sudo ln -s /etc/nginx/sites-available/nginx-lb /etc/nginx/sites-enabled/ ``` 4. **新增主機紀錄到 `/etc/hosts`**。 ```bash $ sudo vim /etc/hosts ``` 新增一行: ``` 127.0.0.1 lbnginx ``` ![新增主機紀錄 `/etc/hosts` 負載平衡](https://hackmd.io/_uploads/BJXftm5Gp.png) <p style="text-align: center;">新增主機紀錄 `/etc/hosts` 負載平衡</p> 5. **測試 Nginx 設定檔語法**。 ```bash $ sudo nginx -t ``` 6. **重啟 Nginx 服務**。 ```bash $ sudo service nginx restart ``` 7. **在瀏覽器中測試**。 * 訪問 `http://lbnginx:8070`,並多次重新整理 (F5)。 * 會看到頁面在 Lighttpd 的預設頁面和 Yahoo! 搜尋頁面之間輪流切換。 ![Nginx 負載平衡測試結果 (Yahoo)](https://hackmd.io/_uploads/SkYkxV5fT.png) <p style="text-align: center;">Nginx 負載平衡測試結果 (Yahoo)</p> ![Nginx 負載平衡測試結果 (Lighttpd)](https://hackmd.io/_uploads/SyVgx49GT.png) <p style="text-align: center;">Nginx 負載平衡測試結果 (Lighttpd)</p> ## 其他工具與概念 * **`fakeroot checkinstall`**:用於建立 `.deb` 套件,提供一種「乾淨」的安裝方式,有助於遵守 FHS (Filesystem Hierarchy Standard) 標準。 ```bash $ fakeroot checkinstall --fstrans --install=no ``` * **`byobu-screen -RUD`**:用於 SSH 遠端開啟多個終端機分頁,提供會話管理功能,即使斷開 SSH 連線也能保持會話運行。 * **`automysqlbackup`**:用於自動備份 MySQL 資料庫。 * **`w3m`**:一個基於終端機的網頁瀏覽工具。 ```bash $ sudo apt install w3m $ w3m https://www.google.com ``` * **`ab` (ApacheBench)**:Apache 提供的工具,用於測試 Web Server 效能。 ```bash $ sudo apt install apache2-utils $ ab -n 1000 -c 100 http://localhost/ # -n requests numbers, -c connecttion ``` * **`iptables`**:Linux 防火牆工具,用於設定網路封包過濾規則。 * `sudo iptables -nL`:列出當前防火牆規則。 * `INPUT`、`OUTPUT`、`FORWARD`:鏈條類型,分別控制進入、發出和轉發的封包。 * `ACCEPT` (接受)、`REJECT` (拒絕但回傳封包)、`DROP` (丟棄不回覆)。 * 範例:`sudo iptables -I INPUT -s0.0.0.0 -ptcp --dport 22 -j ACCEPT` 允許所有來源通過 TCP 22 Port。 * **DMZ (Demilitarized Zone)** 架構:一種網路安全架構,用於隔離內部網路和外部網路,通常將 Web Server 等對外服務放置在 DMZ 區域,以便管制和保護內部 LAN 網段。 * **瀏覽器快取**:瀏覽器會儲存網頁內容以加快下次載入速度。當 Web Server 設定更改後,如果瀏覽器仍然顯示舊內容,可能是快取導致。此時需要清除瀏覽器快取或使用無痕模式測試。

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully