1 of 84

成大資訊營

網路與伺服器架設

2 of 84

上課前設定

請大家用自己的 ubuntu,開啟 command line,然後下這個指令下載上課所需的資料,以及設定上課會用到的 IP,設定完後這個 IP 就會跟你的電腦綁定。

> wget https://vpn.ncku.camp/initvpn.sh

> sudo bash initvpn.sh <拿到的 ID>

> curl ifconfig.me

要輸出你的 IPAddress

3 of 84

上課前設定

上完課如果想把這個 IP 清除可以下這個指令 (注意:7/15 營隊結束後一定要做清除,因為營隊結束後這個 IP 會無法使用,若不清除,電腦會無法上網。):

> sudo systemctl stop wg-quick@wan

> sudo systemctl disable wg-quick@wan

> sudo rm /etc/wireguard/wan.conf

4 of 84

什麼是網路

在日常生活中我們有許許多多的事情是離不開網路的,例如說看影片、玩遊戲、甚至於上課、交作業等等。

那到底什麼是網路呢?

5 of 84

什麼是網路

事實上講白話一點,把很多台電腦用網路線或 WIFI 串聯再一起就是所謂的網路了。

6 of 84

什麼是網路

而在網路上傳輸資料可以比喻成送信。

7 of 84

什麼是網路

首先我們必須先撰寫我們信件的內容

8 of 84

什麼是網路

接這封進信封,並決定用掛號還是平信,寄給誰。

9 of 84

什麼是網路

然後寫下寄件地址跟收件地址

10 of 84

什麼是網路

接著將信交給郵局,由郵局轉送到目標地址區域的郵局再送給目標。

當然如果目標在你家隔壁,你可以直接送就好。

11 of 84

什麼是網路-Application layer

而網路也是一樣的概念,以網頁為例,首先先撰寫內容

12 of 84

什麼是網路-Transport layer

接著決定你現在要用 TCP 還是 UDP,以及從自己電腦裡 瀏覽器程式 送到對方電腦裡的 網頁伺服器程式

13 of 84

什麼是網路-Network layer

接著決定地址的格式使用 IPv4,並寫下自己電腦的 IP Address對方電腦的 IP Address

14 of 84

什麼是網路-Link layer

最後決定要從哪一個 Router (可以想像成郵局) 寄信,當然如果目標就在你目前的區域內,就直接交給他就好。

15 of 84

什麼是網路-Link layer

然後由 Router 轉送給其他 Router 直到到達目的地為止。

16 of 84

什麼是網路-小測驗

下面這張圖顯示的是將資料從 A 電腦送到 B 電腦的路徑

  1. 請問是從哪個 IP 送到哪個 IP
  2. 請問資料送出後這個資料抵達了幾台機器
  3. 其中有幾台是 router。

17 of 84

什麼是網路-小測驗

下面這張圖顯示的是將資料從 A 電腦送到 B 電腦的路徑

  1. 請問是從哪個 IP 送到哪個 IP
  2. 請問資料送出後這個資料抵達了幾台機器
  3. 其中有幾台是 router。

18 of 84

Client Server 架構

提供服務(Service)的人叫做伺服器或服務器(Server),而有該服務需求的人則為客戶端(Client)。可以想像成你今天要訂飯店(訂飯店的服務),因為你有這個需求所以你是 ClientClient 必須要打電話給飯店的客服(Server),提出要訂飯店的需求(發送 request),而客服(Server)經過處理後再回覆訂房是否成功(回覆 response)

19 of 84

TCP vs UDP

20 of 84

TCP vs UDP-UDP

當資料以 UDP 傳輸時,傳送方就只會單純地把資料丟給接收方就不管了。不管接收方有沒有收到。

21 of 84

TCP vs UDP-TCP

當資料以 TCP 傳輸時,傳送方與接收方必須要先三向交握以建立連線(確保兩邊都能正常傳送與接收訊息)。

連線中必須隨時發出 keepalive 訊息讓對方知道自己還在。

22 of 84

TCP vs UDP-TCP

之後每次傳送方發送資料給接收方時,接收方都必須要回傳一個「訊息已收到(ACK)」回來,如果傳送方在一定時間內沒收到確認,就會進行重傳的動作,同時接收方在接收資料時,也會確保資料是按造正確的順序收到。

23 of 84

TCP vs UDP-TCP

最後,如果超過一定時間沒收到 keepalive ,或者對方發送結束連線的要求時就會結束連線。

24 of 84

什麼是協定

協定是指網路中的兩個程式間溝通的規範,可以想像成語言。

比如說瀏覽器對網頁伺服器之間的溝通方式,就必須要按照網頁的協定(HTTP)的規範去溝通。

對於使用者來說最常見的協定有:

  1. 網頁服務:HTTP
  2. 檔案分享服務:FTP or SMB or NFS
  3. 玩遊戲(由遊戲開發商自行定義)

25 of 84

HTTP

HTTP/2 之前的版本是一種建立在 TCP 上的傳輸協定。(HTTP/3 例外,今天不提)

為何需要使用 TCP 是因為網頁他會需要可靠性的傳輸。

可以想像如果今天瀏覽網頁,對方回傳的資料很大,要分多次送,但是部分訊息在中間不見了,你拿到的資料會不會少東少西?

26 of 84

HTTP

這是 HTTP request

這是 HTTP response

27 of 84

HTTP-Request

28 of 84

HTTP-Response

詳細 status: https://http.cat/

29 of 84

HTTP-Lab1

請大家用自己的 ubuntu,開啟 command line,然後下這個指令。�> nc example.com 80

接著輸入這些東西

GET / HTTP/1.1

Host: example.com

User-Agent: nc

Accept: */*

30 of 84

HTTP-Lab1

接著打開瀏覽器按 F12 到 network,

然後網址輸入 http://example.com

點開第一個資料看看

他的 Header 跟�Response

31 of 84

HTTP-Lab2

接著來教大家怎麼去架設一個簡單的網頁。

首先請大家用自己的 ubuntu,開啟 command line,然後下這個指令來安裝 nginx 程序。

> sudo apt install nginx -y

32 of 84

HTTP-Lab2

接著打開自己的瀏覽器,網址輸入 http://<自己的 IP>,應該就會看到一個預設的網頁。

也可以用自己手機的瀏覽器看。

或者也可以把自己的 ip 分享給旁邊的同學,讓他們瀏覽你自己的網頁。

33 of 84

HTTP-Lab3

首先請大家用自己的 ubuntu,開啟 command line 下

> sudo code --no-sandbox --disable-gpu-sandbox --user-data-dir=".vscode-root"

來以管理員權限打開你們的 Visual Studio Code

34 of 84

HTTP-Lab3

現在我們在 /var/www/html 新增一個叫 index.html 的檔案,在裡面隨便打你喜歡的東西,儲存以後將瀏覽器重新整理。

35 of 84

HTTP-Lab3

接著打開 /etc/nginx/sites-enabled/default 這個檔案

36 of 84

HTTP-Lab3

可以仔細觀察他的設定檔:

前面有# 代表註解

listen 是設定要聽的 port (http 預設 port 是 80)

root 是指網頁的根目錄在哪,http request 內的路徑下的檔案會到這個目錄下尋找。

37 of 84

HTTP-Lab3

index 是指預設回傳的檔案,如果 http request 內的路徑沒有檔案名稱(如:/ 或 /data/),那就會回傳 index 後面的檔案(因為有可能沒有這個檔案,所以越前面越優先)

location 則是可以針對各個路徑做個別設定。

38 of 84

HTTP-Lab3

經過仔細觀察,當我們瀏覽 http://<自己的 IP> 時,server 會去電腦裡的 root 下面,把 index 後面的檔案回傳給 client。

39 of 84

HTTP-Lab4

既然我們可以把 Server 自己的檔案傳給 Client ,我們能不能把別台 Server 的網頁再轉傳給 Client 呢?

40 of 84

HTTP-Lab4

請各位再 /etc/nginx/sites-enabled/default 這個檔案的

下面新增一個 location

location /example/ {

proxy_pass http://example.com/;

}

41 of 84

HTTP-Lab4

儲存以後開啟 command line,然後下這個指令來重新啟動 nginx 程序。

> sudo systemctl restart nginx

接著打開自己的瀏覽器,網址輸入 http://<自己的 IP>/example/

42 of 84

HTTP

那甚麼時候會需要用到「將 Client 的 request 轉給其他 Server 並把別台 Server 的網頁轉傳給 Client」這個動作呢?

這很常出現在需要整合前端與後端的時候。

43 of 84

HTTP

前端:使用者在瀏覽器看到的部份,通常以檔案的形式,如:資訊營官網

後端:伺服器內部處理的程式邏輯,通常會用程式語言撰寫成一種較為輕量的網頁服務,如:帳號註冊、帳號登入、更改資料庫

Example: https://github.com/Jimmy01240397/Csie-Camp-NA-EasyWeb

44 of 84

HTTP

前端:餐廳的前台和內部裝潢

後端:廚師

網頁伺服器(nginx): 服務生

  • 新客人進來帶位:轉給前端
  • 客人點菜:轉給後端

45 of 84

DNS

在架完網頁後應該會發現要用 IP 才能瀏覽網頁很醜。

46 of 84

DNS

47 of 84

DNS

全名叫做 Domain Name System,是一種建立在 UDP 的協定。

主要用來查詢 Domain Name 的 IP Address 或是查詢 IP Address 對應的 Domain Name。

那什麼是 Domain Name 呢?

48 of 84

DNS

49 of 84

DNS

50 of 84

DNS

DNS 用的是一種樹狀的查詢架構,這樣的優點是上層 Domain 的管理者可以自由地將下層 Domain 的管理權發給別人。

ref: link

51 of 84

DNS

網路上有很多的域名註冊商,通常你可以用大約 NTD 300 /年,的價格購買到你喜歡的二級域名,網路上也有一些域名託管服務,讓你可以不用架設實體的 DNS Server。

52 of 84

DNS

DNS 的紀錄有很多種類型,而對於一般使用來說,最常見的有五種類型,分別是 SOA、NS、A、AAAA、CNAME

53 of 84

DNS

SOA: Start Of Authority

定義一個DNS權限區域,每個區域只有一個SOA記錄

指定區域名稱、技術聯繫人和各種超時信息

54 of 84

DNS

A: IPv4 Address

提供從主機名到 IPv4 地址的對應

55 of 84

DNS

AAAA: IPv6 Address

提供從主機名到 IPv6 地址的對應

56 of 84

DNS

NS: Name Server

通常用來識別這個區域的權威服務器

以及將子域委託給其他組織的 NS

57 of 84

DNS

CNAME:規範名稱

幫主機添加其他別名

58 of 84

DNS

一個完整的 DNS 記錄檔,大概會長這樣。

59 of 84

DNS-Lab1

請大家用自己的 ubuntu,開啟 command line,然後下這個指令來安裝工具。

> sudo apt install dnsutils

接著輸入以下指令來查詢 root dns server

> dig NS .

接著輸入以下指令來查詢 com 這個域的 dns server

> dig NS com

60 of 84

DNS-Lab1

接著輸入以下指令來查詢 google.com 這個域的 dns server

> dig NS google.com

接著輸入以下指令來查詢 www.google.com 的 IP

> dig A www.google.com

61 of 84

DNS-Lab2

最後讓我來帶著大家架設一個屬於自己的 DNS Server,跟屬於自己的 Domain。

首先我已經將 <你們的ID>.ncku.camp 這個域名的管理權分配給我配給你們的 IP 了。

62 of 84

DNS-Lab2

請大家用自己的 ubuntu,開啟 command line,然後下這個指令來安裝 bind9 程序。

> sudo apt install bind9 -y

63 of 84

DNS-Lab2

接著在 /var/cache/bind/ 新增一個叫 db.<你們的ID>.ncku.camp 的檔案,並寫下下面的資訊。

$TTL 604800

$ORIGIN <你們的ID>.ncku.camp.

@ IN SOA ns.<你們的ID>.ncku.camp. root.<你們的ID>.ncku.camp. (

1 ; Serial

604800 ; Refresh

86400 ; Retry

2419200 ; Expire

604800 ) ; Negative Cache TTL

;

@ IN NS ns.<你們的ID>.ncku.camp.

ns IN A <你們自己的 IP>

@ IN A <你們自己的 IP>

www IN A <你們自己的 IP>

64 of 84

DNS-Lab2

接著修改 /etc/bind/named.conf.local,並寫下下面的資訊。

zone "<你們的ID>.ncku.camp" {

type master;

file "db.<你們的ID>.ncku.camp";

};

65 of 84

DNS-Lab2

儲存完畢後下這個指令來重啟 bind9 程序。

> sudo systemctl restart bind9

接著輸入以下指令來查詢 <你們的ID>.ncku.camp 這個域的 dns server

> dig NS <你們的ID>.ncku.camp

接著輸入以下指令來查詢 www.<你們的ID>.ncku.camp 的 IP

> dig A www.<你們的ID>.ncku.camp

打開自己的瀏覽器,網址輸入 http://www.<你們的ID>.ncku.camp

66 of 84

DNS-Lab3

假設如果我同時有兩個 domain name 都指向同一個 IP,但我網頁想顯示不同的東西怎麼辦,還記得前面設定 nginx 時有一個 server_name 的設定嗎?

請各位修改剛才建立的 /var/cache/bind/db.<你們的ID>.ncku.camp 的檔案,並在最後面新增下面的資訊,來設定一個新的 DNS A 紀錄:

test.<你們的ID>.ncku.camp 對應 <你們自己的 IP>

儲存完畢後下這個指令來重啟 bind9 程序。

> sudo systemctl restart bind9

test IN A <你們自己的 IP>

67 of 84

DNS-Lab3

接著下這個指令,新增一個叫 test 的資料夾在 /var/www

> sudo mkdir /var/www/test

然後在 /var/www/test 新增一個叫 index.html 的檔案,在裡面隨便打你喜歡的東西

68 of 84

DNS-Lab3

接著在 /etc/nginx/sites-enabled/ 新增一個叫 test 的檔案並在裡面寫:

server {

listen 80;

listen [::]:80;

root /var/www/test;

index index.html;

server_name test.<你們的ID>.ncku.camp;

location / {

try_files $uri $uri/ =404;

}

}

69 of 84

DNS-Lab3

儲存完畢後下這個指令來重啟 nginx 程序。

> sudo systemctl restart nginx

打開自己的瀏覽器開兩個分頁,網址分別是:

http://www.<你們的ID>.ncku.camp

http://test.<你們的ID>.ncku.camp

仔細比較是否不相同

70 of 84

HTTPS

現在常看到的網頁基本上都是 HTTPS 比如 google (https://www.google.com.tw/),那 HTTP 與 HTTPS 的差別在哪呢?

71 of 84

HTTPS

沒有加密

有加密

72 of 84

HTTPS

因為 HTTP 本身是沒有加密的,如果你設計的網站需要登入而且傳輸過程又沒有加密,你的帳號密碼是有可能在傳輸的過程中被竊取的。

73 of 84

HTTPS-Lab1

如何設定 HTTPS 呢?由於 HTTPS 重視安全,因此設定前須要做一些安全驗證,並且申請憑證,你會需要輸入你自己的 email 同時你的網站必須要有 Domain Name 因為它會驗證這個 Domain Name 是否是你所持有的。

74 of 84

HTTPS-Lab1

請大家用自己的 ubuntu,開啟 command line,然後下這個指令先停止 nginx。

> sudo systemctl stop nginx

然後下這個指令來安裝 certbot。

> sudo apt install certbot -y

然後下這個指令去申請憑證

> sudo certbot certonly

75 of 84

HTTPS-Lab1

一開始輸入 1 選擇用 standalone

接著他會要求你輸入一些資訊,

如:

你的 email 跟申請憑證網站的 Domain Name

76 of 84

HTTPS-Lab1

接著在 /etc/nginx/sites-enabled/ 修改 test.<你們的ID>.ncku.camp 的站台設定檔,修改成:

server {

listen 443 ssl;

listen [::]:443 ssl;

ssl_prefer_server_ciphers on;

ssl_ciphers 'ECDH !aNULL !eNULL !SSLv2 !SSLv3';

ssl_certificate /etc/letsencrypt/live/test.<你們的ID>.ncku.camp/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/test.<你們的ID>.ncku.camp/privkey.pem;

root /var/www/test;

index index.html;

server_name test.<你們的ID>.ncku.camp;

location / {

try_files $uri $uri/ =404;

}

}

77 of 84

HTTPS-Lab1

儲存完畢後下這個指令來重啟 nginx 程序。

> sudo systemctl restart nginx

用瀏覽器打開 https://test.<你們的ID>.ncku.camp

78 of 84

HTTPS-Lab2

但是修改完以後應該會發現 test.<你們的ID>.ncku.camp 跟原本的不同了,這樣會很不方便,因為通常會希望 http 與 https 看到的內容是一樣的,這時候我們可以設定讓 Client 連上 http 的時候自己轉到 https。

79 of 84

HTTPS-Lab2

在 /etc/nginx/sites-enabled/ 修改你的站台設定檔,以 test 為例在修改成:

server {

listen 443 ssl;

listen [::]:443 ssl;

ssl_prefer_server_ciphers on;

ssl_ciphers 'ECDH !aNULL !eNULL !SSLv2 !SSLv3';

ssl_certificate /etc/letsencrypt/live/test.<你們的ID>.ncku.camp/fullchain.pem;

ssl_certificate_key /etc/letsencrypt/live/test.<你們的ID>.ncku.camp/privkey.pem;

root /var/www/test;

index index.html;

server_name test.<你們的ID>.ncku.camp;

location / {

try_files $uri $uri/ =404;

}

}

server {

listen 80;

listen [::]:80;

server_name test.<你們的ID>.ncku.camp;

return 301 https://$host$request_uri;

}

80 of 84

HTTPS-Lab2

儲存完畢後下這個指令來重啟 nginx 程序。

> sudo systemctl restart nginx

用瀏覽器打開 http://test.<你們的ID>.ncku.camp

可以發現他馬上就跳轉到 https 的網頁

81 of 84

練習

請各位把我們的 camp 網站架起來,網址設為:

camp.<你們的ID>.ncku.camp,並且設定 https ,且設定 http 轉 https。

Camp 網頁原始碼在 https://github.com/swenbaoQQ/csie_camp_web

大家可以下

> cd /var/www

> sudo git clone https://github.com/swenbaoQQ/csie_camp_web

把它下載下來

82 of 84

練習-提示

  1. 我們需要有一個 camp.<你們的ID>.ncku.camp 對應 IP 的 DNS 紀錄
  2. 因為需要 https 因此需要申請憑證
  3. 我們必須要在保留原有站台的情況下新增一個 camp 網站的站台,因此需要新增一個新的站台設定檔。

83 of 84

簡易型網路遊戲

最後大家可以到這個連結下載我用 python 設計並建立在 UDP 下的簡單網路遊戲,裡面有寫如何使用,各位可以跟你旁邊的人玩玩看,或者稍微研究一下裡面的程式碼,也可以自由修改給你的對手一個小驚喜。

https://github.com/Jimmy01240397/pingponeonline

84 of 84

簡易型網路遊戲

要注意的是,當你要做為 server 端時,跳出要求輸入 host and port 的訊息時請直接 enter。

當你要做為 client 端時,跳出要求輸入 host and port 的訊息時請 輸入 server 的 host and port 再 enter。