###### tags: `1111` `lsa` # Web Server [toc] ## Introduce :::info **What is server?** <!--- FIXME: 什麼是 service? 以服務或角色定義 server,或者是以要買 server 這句話去講,要買的需要包含哪些 > 給**要求**會有**回應** > 會把 service 連結到特定主機上,提供service 的主機稱為server ---> - 提出要求的時候,以任何形式提供回應的,就可以稱為 **service** - 用來提供這些 service 的軟體、電腦,就可以稱為 **server** - 種類有很多,database server、file server、**Web Server**... - Server 的功能很多,有些我們每天都會使用 - 遊戲 server、Web Server ::: ### What is Web Server? - First released in 1991 (CERN httpd,由 CERN 跟 World Wide Web Consortium (W3C) 共同開發) <!--- CERN 歐洲核子研究中心 有非常多的研究人員以及資料,有各式各樣的研究需求,在資訊領域基本上都是非常先進的 網路開始於 1970 年代美國國防部的 ARPAnet,最一開始用於軍事上的資料傳遞,用處是為了分享研發資料 一開始都是使用純文字介面來搜尋目錄及檔案等,後來慢慢發展出了 HTML,可以從一個文件連接到另一個文件,可以將一堆散的文件組織再一起 隨著這些的發展,原有的通訊協定漸漸不夠用了,所以有了 HTTP 等通訊協定,有了協定,需要有支援協定的軟體我們才能使用,因此有了支援 HTTP 之類協定的客戶端,ex: chrome firefox... 有了 client 需要有人提供相應的 service,因此 Web Server 出現了 ---> - 透過 HTTP 及其他協定回應 client 端要求的 data <!--- 需要有個溝通的規則 最原始的 HTTP 可以直接用純文字介面去看 demo telent lsa.kija.io GET / HTTP/1.0 <ENTER ENTER> 回來看圖 用 HTTP 通訊協定,就可以跟 Web Server 提出要求,Server 根據提出的要求,給出相應的結果讓 client 進行解析---> - ![](https://i.imgur.com/vja5R9U.png) > [圖片來源](https://en.wikipedia.org/wiki/Web_server) #### HTTP - **H**yper**t**ext **T**ransfer **P**rotocol - 應用層的協定 - 在 client 端跟 server 端 respond & request 的標準 - 預設 port 號:`80 port` - ![](https://i.imgur.com/uoxs9z7.png) > [圖片來源](https://www3.ntu.edu.sg/home/ehchua/programming/webprogramming/http_basics.html) #### port - 埠(ㄅㄨˋ)號 - 用來提供給不同的服務使用,每個 port 提供特定的服務 - 為什麼需要分 port? - 假設所有 data 傳輸到電腦上,電腦需要分辨不同的 data 需要給不同的服務處理 - port number - 以 16 bits 表示,共有 2^16 個可以使用 - 0 ~ 1023 需要超級使用者權限才能取得、使用,用於常見的通訊服務 - `0`:保留埠 - 常用的協定及 port 會記錄在 `/etc/services` 裡面 - demo `less /etc/services` - ![](https://i.imgur.com/SSzyhJz.png) > [圖片來源](https://en.wikipedia.org/wiki/Port_(computer_networking)) - 1024 以上不需超級使用者即可使用 - 有些服務本身就預設開在 1024 以上的 port,ex: `mysql -> 3306` :::info **IANA** (Internet Assigned Numbers Authority) - 提供穩定的網際網路運作環境 - 隸屬於 ICANN (Internet Corporation for Assigned Names and Numbers) - ![](https://i.imgur.com/ubJw6mC.png) - 定義 port number ::: :::info [**DNS**](https://hackmd.io/@9wMI71WWT7iMKm40e4ZcoA/SyNS5AfEs) - 用於將人平常使用的網域名稱轉為機器可讀的 IP 位置 ::: ### 常見的 Web Server 種類繁多,各有各自適合的使用情境 - Nginx - 佔有記憶體少、穩定性高,可以同時承受很大的流量 - 採模組化設計,有許多模組庫與第三方模組庫 - 設計的目標是為了比 Apache 還要好 - Lighttpd - 適合做檔案傳輸 - 低記憶體佔用、低 CPU 負載、速度最佳化 - 支援 cgi & fastcgi - Apache2 - 歷史最悠久 - 以前市占率最高 - 2019 後被 Nginx 超車 - 模組功能強大 - 佔用資源大 ## 安裝及更改 port number ### Nginx - 安裝 - `sudo apt install nginx` - `sudo service nginx status` - 打開瀏覽器,輸入 `127.0.0.1` - Welcome to nginx! - 更改 port number - `cd /etc/nginx` - `cd sites-available` & `cd sites-enabled` - 要做更改前,建議先停止服務 `sudo service nginx stop` - `sudo cp /etc/nginx/sites-available/default /etc/nginx/sites-available/default.backup` - 建議大家複製一份起來,改壞了才有救 - 更改 default - `listen 8080 default_server`:改聽 8080 port - `server_name`:domain name - `root`:網頁根目錄位置 - `index`:預設頁面 - demo ### Lighttpd - 安裝 - `sudo apt install lighttpd` - `sudo service lighttpd status` - 打開瀏覽器,輸入 `127.0.0.1` - `Placeholder page` 你真的成功安裝了 Lighttpd - 更改 port number - `cd /etc/lighttpd` - `cat lighttpd.conf` - `server.modules`:預設啟動哪些模組 - `server.document-root`:網頁根目錄位置 - `server.errorlog` - `server.username` & `server.groupname`:執行服務後切換到哪個使用者權限 - 主要為 web server 不要有太高權限,但 web application 又能作適當程度的寫入 - `server.port` - `index-file.names`:預設頁面 - 要做更改前,建議先停止服務 `sudo service lighttpd stop` - `sudo cp /etc/lighttpd/lighttpd.conf /etc/lighttpd/lighttpd.confbackup` - 更改 `lighttpd.conf` - `server.port = 8081` 改聽 8081 port - demo ### Apache2 - 安裝 - `sudo apt install apache2` - `sudo service apache2 status` - 打開瀏覽器,輸入 `127.0.0.1` - Apache2 Ubuntu Default Page - 更改 port number - `cd /etc/apache2` - `cat apache2.conf`:主設定檔 - 不同的設定會各自在不同的設定檔內 - ![](https://i.imgur.com/F6pHSIq.png) - 要做更改前,建議先停止服務 `sudo service apache2 stop` - `sudo cp /etc/apache2/ports.conf /etc/apache2/ports.confbackup` - 更改 `ports.conf` - `Listen 8082` 改聽 8082 port :::warning 作業要求: Apache2 聽 8090 port Nginx 聽 8091 port Lightpd 聽 8092 port ::: ## Virtual Host <!---一個站可能開了沒有使用,就會造成空轉,因此將多個站合在同一個 server 上進行運作---> - 主要分為 Name-based 以及 IP-based - 在一個 server 上託管多個網站,網站與網站間共享一個 server 的記憶體、CPU、設定檔等 - 不浪費 server 資源,最大化利用價值 - demo ```s= telent ammon.bluet.org 80 GET / HTTP/1.0 ``` ```html= <head><title>BlueT.org Studio</title></head> ``` <hr/> ```s= telent ammon.bluet.org 80 GET / HTTP/1.0 Host: bluet.org ``` ```s= Moved Permanently Location: https://Studio.BlueT.org ``` <hr/> ```s= telent ammon.bluet.org 80 GET / HTTP/1.0 Host: studio.bluet.org ``` - 東西變超多 ### Name-based Virtual Host - 在同一 server 上架有多個不同網站,不同網站間依據名稱判定 - 名稱就是使用者輸入的 FQDN - 一個網站也可以 match 到不止一組的 domain name - ![](https://i.imgur.com/qaVaLYE.png) > [圖片來源](https://www.google.com/url?sa=i&url=https%3A%2F%2Flinuxhint.com%2Fconfigure_apache_virtualhost_ubuntu%2F&psig=AOvVaw2bNX3fUH1DxeD4TlpDQnO2&ust=1667533496409000&source=images&cd=vfe&ved=0CA0QjRxqFwoTCOCKisaMkfsCFQAAAAAdAAAAABAh) - 一個 IP 位址就可以配多個 FQDN 的網站 ### IP-based Virtual Host - 在一台主機上,開設多個 IP 位址的虛擬主機,可以針對只聽特定的網卡 - ![](https://i.imgur.com/3rJldCD.png) >[圖片來源](自己畫的) <!---將多個 IP 位址 Binding 在同一張網卡上---> :::info **Port-based Virtual Host** 利用 port 來區別不同的網站,因為不會在常見的 port 上,可以用在內部或私人使用 ::: ### Lab - 新增網頁根目錄資料夾 `cd /var/www/vhost` & `sudo mkdir nginx1` - `sudo vim index.html` ```s= This is nginx1 server. ``` - 新增 host 紀錄 `sudo vim /etc/hosts` - `127.0.0.1 nginx1.LSA11101.lala` - 更改 nginx-vhost 設定 `cd /etc/nginx/sites-available/` - `sudo cp -a default nginx-vhost` & `sudo vim nginx-vhost` ```s= server { listen 8080; server_name nginx1.LSA11101.lala; root /var/www/vhost/nginx1/; location / { try_files $uri $uri/ =404; } } ``` - 將檔案 soft link 至 sites-enabled - `sudo ln -s /etc/nginx/sites-available/nginx-vhost /etc/nginx/sites-enabled/` - 確認 nginx 服務狀態 - `sudo nginx -t` - 重啟服務 - `sudo service nginx start` - 瀏覽器查看結果 - `nginx1.LSA11101.lala:8080` ## Reverse Proxy & Load Balance :::info **Proxy** <!---舉例來說,最近大家都在看 NBA 的總冠軍賽,而大家也都想去 www.nba.com 截取最新消息,數學系有人要看,他必需連到 www.nba.com 取得資料一次,而如果生科系有人也要看,他也必需到 www.nba.com 去再截取一次,如果輔大今天有卅個人要看,那就必需去 www.nba.com 截取資料卅次,這對我們對外僅有的 T1,TANet 上僅有的兩條 T1 的頻寬來說是多麼的浪費,而且你也會覺得用起來非常非常的慢。假始今天我們有一台 Proxy Server,而所有的輔大 WWW 使用者都有設定這台 Proxy Server,那麼情況就改變不同了。第一個要讀 www.nba.com 的使用者會先到這台 Proxy Server 上先找看看有沒有 www.nba.com 的最新資料,如果沒有,則由這台 Proxy Server 幫他代理到 www.nba.com 抓取一份資料之後放在 Proxy Server 上也傳送給第一位使用者。而最辛運的是第二位以後的使用者,當他要連往 www.nba.com 時,他的機器會先到 Proxy Server 上看看,結果有資料,則就直接由 Proxy Server 取回資料即可---> - 代理,client 透過 proxy 向 server 端發出 request - ![](https://i.imgur.com/ogZGVw3.png) > [圖片來源](https://linux.vbird.org/linux_server/centos6/0420squid.php) ::: ### Reverse Proxy - 將 client 提出的 request 發給不同的 server 處理 - ![](https://i.imgur.com/yYRyyjs.png) > [圖片來源](https://www.jyt0532.com/2019/11/18/proxy-reverse-proxy/) - 好處 - server 的 IP 位址或 port 更改時,只需向 proxy 更改 - proxy 本身會有快取,不用每次都向 server 發出 request ![](https://i.imgur.com/OXN6U77.jpg) #### Lab - 停止 Nginx 服務並更改 nginx-vhost 設定 - `cd /etc/nginx/sites-available/ `(先到其根目錄下的檔案) - `sudo service nginx stop` (停止服務) - `sudo vim nginx-vhost`(新增proxy) ```s= server { listen 8080; server_name nginx1.LSA11101.com; location / { proxy_pass http://lsa.kija.io; } } ``` - 確認 nginx 服務狀態 - `sudo nginx -t` - 重啟服務 - `sudo service nginx start` - 瀏覽器查看結果 - `nginx1.LSA11101.com:8080` ### Load Balance - Reverse Proxy 的一個功能 - 負載平衡,將流量合理分配,以提升各個 server 的資源使用率及可用性 - 避免流量集中給同一台 server 而造成**超載/過載/爆掉**而使服務無法正常運行 - 避免 server 開著卻沒有用到而造成浪費 #### Lab - 新增設定檔 - `cd /etc/nginx/sites-available/` ```s= sudo vim nginx_LB ``` :::info **upsteam** - 定義分流的 IP - 預設用 round robin ::: ```shell= upstream lsa.lab { server lsa.kija.io; server tw.search.yahoo.com; } server { listen 8070; server_name nginx1.loadBalance.com; location / { proxy_pass http://lsa.lab; } } ``` - 建立 soft link 到 `sites-enabled` - `sudo ln -s /etc/nginx/sites-available/nginx_LB /etc/nginx/sites-enabled` - 確認設定檔狀態 - `sudo nginx -t` - 重啟服務 - `sudo service nginx start` - 新增 host 紀錄 sudo vim /etc/hosts - `nginx1.loadBalance.com` - 開啟瀏覽器進行測試 - `nginx1.loadBalance.com` 然後一直重新整理 ![](https://i.imgur.com/3tYRJEO.png) :::info ## Lighttpd Proxy - 檔名前面的數字代表起始順序 - `sudo vim 99-lighttpd1.conf` ```shell= server.modules += ( "mod_proxy" ) $HTTP["host"] == "lighttpd1.proxy.LSA11101.lala" { proxy.balance = "hash" proxy.server = ( "" => (("Host" => "127.0.0.1", "port" => "8080",))) } ``` - 新增 host 紀錄 `sudo vim /etc/hosts/` - `127.0.0.1 lighttpd1.proxy.LSA11101.lala` <!---- 新增網頁根目錄資料夾 `cd /var/www/vhost` & `sudo mkdir lighttpd1` - `sudo vim index.html` ```s= <h1>This is lighttpd1 vhost server.</h1> ```---> - 更改 port - `sudo vim lighttpd.conf` ```s= server.port =8081 ``` - 啟用設定檔 ```shell= sudo lighttpd-enable-mod Enable module: lighttpd1 ``` :::