Google Code Prettify

顯示具有 network 標籤的文章。 顯示所有文章
顯示具有 network 標籤的文章。 顯示所有文章

2023年1月10日 星期二

GCP: Configuring Networks via gcloud

 準備環境

開啟 Cloud Shell,看一下它是什麼 OS ?

cat /etc/os-release

看來是 Debian,因為這篇是要設定網路組態,需要用到 ping 指令,先執行如下指令安裝:

sudo apt install iputils-ping
進入主題前,先了解以下基本觀念:
  1. VPC (Virtual Private Cloud) 在 GCP 中是彼此隔離的。

  2. 每個 Google Cloud project 建立時,系統會自動建立一個預設的 subnet 網路。

Create network

  • 基礎觀念

  1. VPC 分兩種模式 (mode): auto、custom。

  2. 在同一個 project 裡,VPC 名稱不能重複。

  3. 每個 project 可以有四個 VPC

  • 建立 network

建立一個 custom 模式的網路,指令如下,網路命名為 labnet。

gcloud compute networks create labnet --subnet-mode=custom

上面的指令說明如下:

  1. gcloud: 調用 Cloud SDK 裡的 gcloud 命令

  2. compute: gcloud 指令集之一

  3. network: compute 的指令集之一

  4. create: 執行的動作

  5. labnet: 網路名稱

  6. --subnet-mode=custom: 指定要建立的網路模式為 custom

點選 Google Cloud Console 左邊選單「網路 > 虛擬私有雲網路 > 虛擬私有雲網路」


顯示出如下畫面,確實建立了一個名稱為 labnet 的 Network。

Create a subnetwork

  • 基礎觀念

  1. 一個 project 可以跨好幾個 region

  2. subnetwork 的名稱在同一個 project 的同一個 region 裡不能重複

  3. subnetwork 的名稱在同一個 project 可在不同 region 出現兩次

  4. 每個 subnetwork 要設定一個 IP 網段,這個網段在同一 project 的同一 region 中不可與其它 subnetwork 衝突。

  • 建立 subnetwork

建立 subnetwork 指令如下:

gcloud compute networks subnets create labnet-sub --network labnet --region asia-east1 --range 10.0.0.0/28
這個 subnetwork 的 IP 範圍會是 10.0.0.0 ~ 10.0.0.255
Viewing networks
gcloud compute networks list

顯示出共有兩個網路,一個 default、一個 labnet,與從控制台的「虛擬私有網路」看到是一樣的,要看網路的詳細資料,指令如下:
gcloud compute networks describe labnet
最後一個參數是網路名稱,這裡查看剛剛新建立的 labnet,得到如下結果:

List subnets
gcloud compute networks subnets list
如上指令查看 subnets,得到的結果非常多,找到 labnet-sub 的 subnetwork,內容如下:

內容太多不好找,可以執加過濾條件,如下,只會列出在台灣彰濱機房的 subnetwork。

gcloud compute networks subnets list --filter=“REGION: asis-east1”
Creating firewall rules
  • 基礎觀念
  1. network 的模式 (mode) 為 custom 時,系統不會預設建立任何防火牆規則。

  2. 防火牆規則是定義在 network 層。

  3. 防火牆規則的名稱,在同一個 project 中不可重複。

gcloud compute firewall-rules create labnet-allow-internal --network=labnet --action=ALLOW --rules=icmp,tcp:22 --source-ranges=0.0.0.0/0
  • 建立防火牆規則
上面指令為 network labnet 建立了一條防火牆規則,名為 labnet-allow-internal,允許通過 icmp 及 tcp:22 port,連線來源不設限,說明如下:
  1. firewall-rules: compute 指令的子類別

  2. create: 這次指令要做的事 (動詞)

  3. labnet-allow-internal: 防火牆規則名稱

  4. --network=labnet: 指出這個防火牆規則要套用到那個 network

  5. --action: 有兩個值 ALLOW (允許)、DENY (拒絕),這裡是要開通防火牆,所以用 ALLOW。

  6. --rule=icmp,tcp:22 : 指出要開通的通訊協定 (icmp、tcp) 和 port (22)。

  7. --srouce-ranges=0.0.0.0/0: 規定來源 IP 的範圍

Viewing firewall rules details
gcloud compute firewall-rules describe [FIREWALL_RULE_NAME]
這個指令可以查看防火牆規則的細節,執行後產生的結果如下:

從上面的細節內容 direction: INGRESS,可以看出來,開通的這個防火牆是單向的,只允許由外向內。
Create another network
gcloud compute networks create privatenet --subnet-mode=custom
上面指令,會建立一個名稱為 privatenet 的 network,其 mode=custom,執行結果如下圖,訊息顯示,這個時候這個 network 還沒有套用任何防火牆規則。
gcloud compute networks subnets create private-sub --network=privatenet --region=asia-east1 --range 10.1.0.0/28
上面指令執行結果如下圖,在 network privatent 中建立了一個名稱為 private-sub 的 subnetwork (子網路)。
Create  the firewall rules for privatenet
gcloud compute firewall-rules create privatenet-deny --network=privatenet --action=DENY --rules=icmp,tcp:22 --source-ranges=0.0.0.0/0
這個指令建立的防火牆規則和前面剛好相反,這個規則允許除 icpm、tcp:22 的所有連線通過,執行結果如下:
想看一下這條規則的詳細說明,如下用如下指令:
gcloud compute firewall-rules describe privatenet-deny
到目前建立了兩個 network,可以用以下指令列出來看看
gcloud compute firewall-rules list --sort-by=NETWORK

上面指令包含預設的都會列出來,如果只想列出我們自行建立的,可以加上過濾條件。

gcloud compute firewall-rules list --sort-by=NETWORK --filter=“NETWORK != ‘default’”
Create VM instances

查一下到目前為止,我們建立了那些 subnets。

gcloud compute networks subnets list --filter=“REGION = ‘asia-east1’”

執行結果如下:

接下來要在 labnet-sub 及 privatek-sub 兩個 subnets 中各建立一個 VM,用來測試網路是否有通。
  • Create the pnet-vm instance
gcloud compute instances create pnet-vm --zone=asia-east1-c --machine-type=n1-standard-1 --subnet=private-sub

執行結果如下,在 AZ = asia-east1-c 的機房,在子網路 private-sub 裡建立了名稱為 pnet-vm 的 VM,內部 IP: 10.1.0.2,外部 IP: 35.221.157.5。

  • Create the lnet-vm instance
gcloud compute instances create lnet-vm --zone=asia-east1-c --machine-type=n1-standard-1 --subnet=labnet-sub

執行結果如下,在 AZ = asia-east1-c 的機房,在子網路 labnet-sub 裡建立了名稱為 lnet-vm 的 VM,內部 IP: 10.0.0.2,外部 IP: 34.80.241.172。

檢查上面建立的兩個 VM,列出來看看,指令如下:

gcloud compute instances list --sort-by=ZONE --filter="ZONE='asia-east1-c'"

結果如下, STATUS 都是 RUNNING,正常在運作。

Explore the connectivity

檢查一下防火牆,在自己的電腦開個命令列視窗,ping 上面的兩個外部 IP。

結果是 lnet-vm 可以通,pnet-vm 不通,如預期!

2022年12月2日 星期五

Azure: Network Security Group

  • NSG (Network Security Group, 網路安全性群組) 是一種網路流量篩選器,可以和 VM 的虛擬網卡或 VNet 的子網路結合。

  • NSG 中包含防火牆的對內、對外規則,修改規則只會影響形成的新連線。 建立新規則或在網路安全性群組中更新現有規則時,它只會套用至新的流程和新連線。 現有的工作流程連線不會隨著新的規則更新。

  • 建立 VM 時,Azure 預設會建立一個相對應的 NSG,如果要改變 VM 對防火牆等網路設定,要修改 NSG,不能用傳統上管理網路的指令直接修改。如下圖,當建立一個命名為 VM4 的 VM 時,系統自動建立了一個 NSG 掛在該 VM 上,如果要修改 VM4 的網路設定,要修改 VM4-nsg 這個 NSG 裡的設定,千萬不要在 VM4 裡下傳統網路管理指令。


    • 說明上圖的幾個項目:

    1. Inbound Security Rules 是由外向內連線的規則,Outbound Security Rules 是由內向外連線的規則。

    2. 每個連線要通過防火牆,會比對上面的條件,由 Priority 小的開始比對,符合了就可以通行,不再往下比對。

    3. Name 可以隨便取,可讀性高就好,但是如上圖,有預先設定好幾個了,如下:

       規則說明
      1AllowVNetInBound
      允許來自同一 VNet 或對等互連 VNet 的對內流量
      2AllowAzureLoadBalancerInBound
      允許來自任何 Azure 負載平衡器 IP 位址的對內檢測流量
      3DenyAllInbound
      特殊規則,確保任何前面的規則未能比對出來的對內流量都會被擋下。
      4AllowVNetOutBound
      允許源於此一 VNet 或前往對等互連 VNet 的對外流量
      5AllowInternetOutBound
      允許此一 VNet 內的 VM 前往 Internet
      6DenyAllOutBound
      特殊規則,確保任何前面的規則未能比對出的對外流量都會被擋下。
      預設規則無法移除,但可以建立較高優先順序的規則來覆寫預設規則。
    4. 在 Source 和 Destination 欄位,有如下標籤方便設定 NSG 規則:
    5. Service Tag說明
      1VirtualNetwork
      所有的虛擬網路定址空間皆包含在內,包含本地及對等互連的 VNet。
      2Internet
      所有公共 IP 位址,不論是 Azure 或外界持有皆然。
      3AzureLoadBalancer
      你所部署的 Azure 負載平衡器的虛擬 IP 位址
      4AzureCloud
      Azure 的公共 IP 位址空間
      5Storage
      Azure 儲存體服務的 IP 位址空間
  • 如下圖,VM 3、VM 4 在同一個 subnet,如果它們的網路設定一樣,想要統一管理,可以把它們預設綁在 VM 上的 NSG 移除,並設定一個新的 NSG 綁在 subnet 3 上。(在 example 中會說明怎麼做)

example 
  1. create NSG
    進入如上畫面,按【Create】後,進入如下畫面,填入 NSG 名稱。
    按【Review + create】後進入下面畫面,再按【Create】即成功建立一個 NSG。

  2. 設定 NSG
    如上,剛剛才建立的 subnet3-nsg 已經有預設建了一些 Inbound security rules 和 Outbound security rules,要很嚴謹的話,通常會把這些都刪除,只加上自己要的規則。
    因為我們希望可以 ssh 到 VM 3、VM 4,如下圖在「Inbound security rules」中按【Add】。
    popup 出如下畫面後,在「Service」下拉選單選擇「SSH」。
    按下【Add】後,會出現如下畫面,已經加入新的規則,因為 Priority 100,所以排最上面。

  3. 掛載 subnet-nsg 到 subnet

    如上圖,在「Virtual networks」中找到 VNet2,選擇「Subnets」,裡面只有一個 subnet3,點選後出現 subnet3 的規則選項,在「Network security group」下拉選單中選擇「subnet3-nsg」後按【Save】。
  4. 修改 VM 4 的 Networking

    查看 VM 4 的網路設定,原本的 VM4-nsg 及剛設定的 subnet3-nsg 同時存在,從 subnet3 外連線進去或由 VM 4 連出 subnet3 會同時受這兩個規則限制,與我們想要的不同,要移除 VM4-nsg。
    點選上面紅框中的 vm491-z1 會進到下圖,目前的 NSG 是 VM4-nsg,要將它卸載,下拉選單改選為 None 後按【Save】。
    再重新觀察 VM4 下的 Netowkring,如下圖,只剩下 subnet3-nsg。
    VM4-nsg 現在不想用了,可以刪除,如下圖按【Delete】。

2015年5月26日 星期二

byte ordering functions

前一篇「Linux Network Programming - 初體驗」目的很單純,就是快速的對 socket 有基本的認識,這一篇要說明 byte ordering 的問題及解決辦法!

在一般人的直覺裡,如果一個 short 有兩個 byte,在記憶體中應該就是由左到右放,就像寫字一樣,由左到右寫,那麼就會是高位元放在左、低位元放在右,這就是 big-endian byte order。可偏偏並非所有的電腦都是這麼放的! 有些電腦是低位元放在左,高位元放在右,這稱為 little-endian byte order。而 socket 的傳輸資料不管原來是什麼型別,傳輸過程一定會是以 byte array 的方式傳輸,接收端接收後,再依原先約定好的格式還原成各種型別。在網路上傳輸的 byte array 順序,是規範成 big-endian。

上圖是「Unix Netowrk Programming」的3.4節中的一個插圖,用來說明 big-endian 和 little-endian 的差別。在開始寫程式前,一定要先了解這些基本的知識,並且知道 C 提供了那些函式來解決這個問題!

回過頭去看前一篇的 server 程式,有如下一段程式碼:
22 servaddr.sin_family = AF_INET;
23 servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
24 servaddr.sin_port = htons(1513);
23、24行中呼叫的 htonlhtons 就是本篇要介紹的,他們會將如 1513、INADDR_ANY 這樣的常數值,轉成合乎網路傳輸所需要的值 (轉換後如果值改變的話,基本上就是高位元、低位元排列順序變了造成的!)。
兩個函式是 host to netowrk 的縮寫,l 和 s 就是 long 和 short,htonl 用來處理 32 位元的值,htons 用來處理 16 位元的值。要特別注意,就算是在 64 位元電腦上,htonl 還是只用來處理 32 位元的值!




2015年5月10日 星期日

BCD pack & unpack

在程式裡的 I/O 和 CPU 計算比起來,速度差距非常大,網路傳輸又是 I/O  中比較慢的一種,所以,常可見到網路傳輸的資料,會先經過壓縮後再傳輸,接收端接到後再解壓縮。BCD 是一種常用的壓縮技術,當要傳輸的資料中,某一段確定是數字,即可將該段的資料以 BCD 壓縮後傳輸,例如:
123456789665,或許它代表著12點34分56秒789毫秒665奈秒,如果不壓縮直接傳就是 12 個 bytes,BCD 則只會有 6 個 bytes,為什麼? 說明如下:
  1. 一個 byte 有 8 個 bits,用來存數字,實際上只會用到後面 4 個 bits,前面的 4 個 bits 永遠為 0000,例如 5 的 8 個 bits 會是 00000101 (二進位表示法),9 的 8 bits 為 00001001。
  2. BCD 用一個 byte 來存兩個數字,前 4 個 bits (高位元) 存一個數字,後 4 個 bits 再存一個數字,所以,如果有兩個數字 95,用 BCD 儲存就會是 10010101,前 4 個 bits 是 9,後 4 個 bits 是 5。
底下是 BCD 的程式:

public class BCD {
 static public byte[] pack(long number) {
  byte hi, lo;
  String s = String.valueOf(number);
  byte[] data = s.getBytes();
  byte[] bcd = new byte[s.length() / 2];
  for (int i = 0; i < bcd.length; i++) {
   hi = (byte)(data[i * 2] << 4);
   lo = (byte)(data[i * 2 + 1] & 0x0f);
   bcd[i] = (byte)(hi | lo);
  }
  return bcd;
 }
 static public long unpack(byte[] pack, byte[] data) {
  byte hi, lo;
  long number = 0L;
  for (int i = 0; i < pack.length; i++) {
   hi = (byte)((pack[i] >> 4) & 0x0f);
   lo = (byte)(pack[i] & 0x0f);
   data[i * 2] = hi;
   data[i * 2 + 1] = lo;
   number = number * 100 + (hi * 10) + lo;
  }
  return number;
 }
}

應該很容易看的懂,pack 就是將正常的資料壓縮成 BCD 格式,unpack 是將 BCD 格式的資料還原。測試程式如下:
要被壓縮的資料為 number,值為 123456789665,參考下面的輸出,可以看到 BCD 長度只有 6 bytes,其 hex 值即是我們要傳輸的值; 把 BCD 資料解壓縮,即可回 number 的值。
bcd len: 6
bcd value: [B@439f5b3d
bcd value (hex): 123456789665
data len: 12
data value: [B@685f4c2e
data value (hex) 010203040506070809060605
number: 123456789665
要特別注意的是,上面 unpack 程式中,高位元的資料在向左 shift 4 位到低位元後,一定要再 & 0x0f,將高位元清為 0,因為 shift 時,如果最高的 bit 為 1,往左 shift 4 位,高位的 4 個 bits 會全部變成 1,例如最前面例子舉的 95,二進位是 10010101,5 是存在低位元,只要將高位元清成0 ( & 0x0f),即可得到 5,但是 高位元的 9 向左 shift 4 位後會是 11111001,所以要將高位元再清為 0 (& 0x0f)。