章節 2 Ubuntu 的基本設定

本章主要會說明如何透過 SSH 存取虛擬機器與虛擬機器基本設定。

2.1 事前準備

從這個章節開始會出現一些特殊前綴的方框(如下表)表示,不同的前綴代表不同種類的終端機,或是使用終端機的身份,請多多注意。

  • PS: powershell 指令前綴

    dir
  • $: 終端機指令前綴(一般使用者)

    ls -al
  • #: 終端機指令前綴(超級使用者)

    sudo rm -rf ~/Downloads
  • OUTPUT: 終端機輸出

    total 12
    drwxrwxr-x  3 kuaz kuaz 4096 Sep 22 02:11 ./
    drwxr-x--- 15 kuaz kuaz 4096 Oct 10 22:30 ../
    drwxrwxr-x  6 kuaz kuaz 4096 Oct  6 14:06 School/

2.2 APT

在 Ubuntu 上安裝任何程式大多都是用 APT (Advanced Packaging Tools) 安裝,這裡有兩個指令,用 && 串接在一起:

sudo apt update && sudo apt upgrade -y
  • apt update: 更新可安裝的套件列表或版本

  • apt upgrade: 安裝程式

  • &&: && 之前的指令執行成功才會接續執行 && 後面的指令

  • -y, --yes, --assume-yes: 自動對安裝提示回答 yes,安裝時會提示是否確認要安裝該軟體,因為我們清楚自己在做什麼為了方便而把提示關掉

2.3 安裝驅動程式

在安裝驅動程式之前,需要從上面的設定將 Guest Additions 的光碟映像檔掛載至虛擬主機上面。

VirtualBox 插入 Guest Additions ISO

圖 2.1: VirtualBox 插入 Guest Additions ISO

掛載後先在 /media/ 資料夾建立新的 iso 資料夾

sudo mkdir /media/iso

查詢目前掛載的位置

lsblk

掛載光碟至指定資料夾

sudo mount /dev/sr0 /media/iso

安裝安裝程式所需的依賴套件

sudo apt update && sudo apt install bzip2 gcc make perl -y

安裝驅動程式

sudo /media/iso/VBoxLinuxAdditions.run

2.4 存取虛擬主機的網路

首先將虛擬主機關閉電源,關閉電源後要新增一張「僅限主機」的網路卡。對虛擬主機右鍵後點選設定。

VirtualBox 對虛擬主機右鍵

圖 2.2: VirtualBox 對虛擬主機右鍵

接著,依序點選「網路」 → 「介面卡 2」 → 「僅限主機」介面卡 → 「進階」,記下目前的 mac 位址。

VirtualBox 虛擬主機位址

圖 2.3: VirtualBox 虛擬主機位址

再來回到虛擬主機安裝 net-tools

sudo apt install net-tools

確認目前的裝置名稱,可以看到 08:00:27:59:b3:11 與剛才新增的介面卡 mac 位址相同。這裡 enp0s8 即為剛才插入的新的「僅限主機」網路卡,這個裝置名稱需要把它記下來。

另外一張網路卡 enp0s3 的網路卡是預設 NAT 介面的虛擬主機網路卡。

ifconfig -a
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::a00:27ff:fed3:c805  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:d3:c8:05  txqueuelen 1000  (Ethernet)
        RX packets 28  bytes 5374 (5.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 56  bytes 6063 (6.0 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::a00:27ff:fe59:b311  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:59:b3:11  txqueuelen 1000  (Ethernet)
        RX packets 870  bytes 79177 (79.1 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 630  bytes 111436 (111.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 84  bytes 6368 (6.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 84  bytes 6368 (6.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

可以看到剛才新增的的網路卡沒有 ip 位址,這是因為系統沒有為這張網卡打開 dhcp 的設定。

我們可以透過修改 netplan 的設定將 dhcp 伺服器打開。將 enp0s8 的設定添加在 enp0s3 下面。

sudo vim /etc/netplan/00-installer-config.yaml

/etc/netplan/00-installer-config.yaml

# This is the network config written by 'subiquity'
network:
  ethernets:
    enp0s3:
      dhcp4: true
    enp0s8:
      dhcp4: true
  version: 2

套用剛才的設定

sudo netplan apply

再次確認目前虛擬主機的 ip 位置

ifconfig
enp0s3: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 10.0.2.15  netmask 255.255.255.0  broadcast 10.0.2.255
        inet6 fe80::a00:27ff:fed3:c805  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:d3:c8:05  txqueuelen 1000  (Ethernet)
        RX packets 32  bytes 7734 (7.7 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 71  bytes 8490 (8.4 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

enp0s8: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.56.101  netmask 255.255.255.0  broadcast 192.168.56.255
        inet6 fe80::a00:27ff:fe59:b311  prefixlen 64  scopeid 0x20<link>
        ether 08:00:27:59:b3:11  txqueuelen 1000  (Ethernet)
        RX packets 1068  bytes 98415 (98.4 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 791  bytes 132687 (132.6 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 84  bytes 6368 (6.3 KB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 84  bytes 6368 (6.3 KB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

後續我們就可以透過剛才新增的網路卡 ip 位址 192.168.56.101 存取這台虛擬主機。

2.5 UFW

UFW(Uncomplicated Firewall)是預設在 Ubuntu 系統上的防火牆,這裡先為了下一節 OpenSSH 而打開埠號 60000

首先用 status 查詢 UFW 服務的狀態,這裡需要輸入超級使用者 (sudo) 的密碼。

sudo systemctl status ufw

如果服務沒有啟用,使用指令 enable 啟動。

sudo systemctl enable ufw

status 確認防火牆狀態

sudo ufw status

看來預設的 UFW 是關閉的

Status: inactive

接著用 enable 指令打開防火牆

sudo ufw enable

查詢防火牆狀態

sudo ufw status
Status: active

允許埠號 60000 從任何地方連入

sudo ufw allow 60000

查詢防火牆狀態

sudo ufw status

目前只有兩條規則,分別是 從任何地方連入埠號 60000 與 ipv6 從任何地方連入埠號 60000

Status: active

To                         Action      From
--                         ------      ----
60000                      ALLOW       Anywhere
60000 (v6)                 ALLOW       Anywhere (v6)

2.6 Windows 終端機

Windows 的用戶建議可以安裝 Windows 終端機。可以參考附錄的 Windows 終端機 介紹。

2.7 OpenSSH

在這個小節會逐步解釋 OpenSSH 的使用方法,從 OpenSSH 客戶端安裝、產生 SSH 金鑰再來是連線。

2.7.1 概述

OpenSSH 是 SSH(Secure Shell)一個開源的版本。SSH 是一種透過 SSH 傳輸協定來管理系統、傳輸檔案的一個系統套件。它現在被廣泛的使用在各個資料中心與大企業中。

SSH 傳輸協定驗證流程 圖片來源:https://www.ssh.com/academy/ssh

圖 2.4: SSH 傳輸協定驗證流程 圖片來源:https://www.ssh.com/academy/ssh

2.7.2 安裝 OpenSSH 客戶端

要連接到虛擬機器的 OpenSSH 伺服器之前,你需要有一個可以讓你連接的 OpenSSH 用戶端。

如果你是 Linux 或是 MacOS,通常都有內建 OpenSSH 用戶端,可以直接跳至下一節。如果是 Windows 系統,需要在選用功能裡面啟用 OpenSSH 用戶端。

  • MacOS 或 其他 Unix-like 系統

可以用指令 which ssh 查詢 ssh 客戶端有無安裝,如沒有安裝可以使用套件管理程式安裝 openssh-server,以 Ubuntu 為例:

sudo apt install openssh-server
  • Windows 系統

Windows 11 已經有內建 OpenSSH 客戶端,要確認有無安裝一樣可以打開 PowerShell 並輸入 ssh 檢查指令有無安裝。

如沒有安裝可以使用下列流程進行安裝

Windows 11 的安裝流程:

  1. 點擊「開始」

  2. 打開「設定⚙」

  3. 選取「應用程式」 ➜ 點選「選用功能」

  4. 請在頁面頂端點選「檢視功能」,然後在搜尋列中搜尋「OpenSSH 用戶端」,點選安裝

Windows 10 的安裝流程:

  1. 點擊「開始」

  2. 打開「設定⚙」

  3. 選取「應用程式」 ➜ 「應用程式與功能」 ➜ 找到黑體字「程式與功能」,並點選下面的「選用功能」

  4. 在已安裝的篩選列上面篩選 ssh ,如果沒有,請在頁面頂端點選「新增功能」,找到「OpenSSH 用戶端」後,點選安裝

安裝完成後,你可以打開命令提示字元或是 PowerShell 輸入指令 ssh 來確認是否安裝完成。如果正常出現指令描述,代表成功安裝。

ssh
usage: ssh [-46AaCfGgKkMNnqsTtVvXxYy] [-B bind_interface]
           [-b bind_address] [-c cipher_spec] [-D [bind_address:]port]
           [-E log_file] [-e escape_char] [-F configfile] [-I pkcs11]
           [-i identity_file] [-J [user@]host[:port]] [-L address]
           [-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
           [-Q query_option] [-R address] [-S ctl_path] [-W host:port]
           [-w local_tun[:remote_tun]] destination [command]

2.7.3 產生 SSH 金鑰

使用 ssh-keygen 指令產生金鑰,加密方式有 dsa、ecdsa、ecdsa-sk、ed25519、ed25519-sk 與 rsa,預設的加密方式是 rsa,詳細指令用法可以透過 ssh-keygen --help 指令查詢,這裡我們用最簡單的 ssh-keygen 指令。

ssh-keygen

產生後,Windows 的用戶預設會把金鑰儲存在 C:\Users\<USERNAME>\.ssh\ 的位置,而 Linux 的用戶會儲存在 ~/.ssh/ 的位置。

這裡會詢問你要不要把產生的 SSH 金鑰重新命名,如果沒有複數的金鑰一般不會動到它的名字,按 Enter↩︎,接續下一步。

Generating public/private rsa key pair.
Enter file in which to save the key (C:\Users\<USERNAME>/.ssh/id_rsa):

這一步再詢問你需不需要將 SSH 金鑰加密,如果加密了,每次連線都需要輸入密碼。如果怕麻煩不想設定密碼就留空按 Enter↩︎ 進入下一步。

Created directory 'C:\Users\<USERNAME>/.ssh'.
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

產生金鑰會順帶產生這個金鑰的指紋。

Your identification has been saved in C:\Users\<USERNAME>/.ssh/id_rsa.
Your public key has been saved in C:\Users\<USERNAME>/.ssh/id_rsa.pub.
The key fingerprint is:
SHA256:8NE76AD294Tjze76pEPtvZgqaqw9OuCF7T8HWPo6fUc qaz85@DESKTOP-OH6HA84
The key's randomart image is:
+---[RSA 3072]----+
|                 |
|         .       |
|    o . . .      |
|   . + o + .     |
|  o + o S.+      |
|.. = . =.E..     |
|..o.o ..+.=.     |
| ..+++.o.=.o.    |
|  o**++.=** ..   |
+----[SHA256]-----+

產生完畢,儲存在 C:\Users\<USERNAME>\.ssh\id_rsa 的檔案是私鑰(private key),而另一個 id_rsa.pub 的檔案是公鑰(public key)。

當你丟失了遠端主機的金鑰,你再也不能透過遠端存取遠端的伺服器,只能透過直接接觸那台主機來更新 SSH 金鑰,所以要妥善保存。

2.7.4 上傳 SSH 金鑰

當你擁有了 SSH 金鑰,接下來要將公鑰上傳至遠端的伺服器。另外公鑰給別人看到是沒問題的,公鑰並不能用來產生私鑰,它是用來認證是否跟你所持有的私鑰相吻合。

  • Linux 系統

如果你是的系統是 Linux 那上傳的指令會稍微短一些,上傳至遠端電腦的指令如下:

ssh-copy-id -i ~/.ssh/id_ed25519.pub -p 22 asis@192.168.56.101
  • -i: i 參數代表的是你要上傳的公鑰的檔案路徑

  • -p: p 參數則是目的地主機 OpenSSH 伺服器的埠號

  • id_ed25519.pub 為我產生的公鑰,如果你前面是照著我的步驟產生,這裡應該改為 id_rsa.pub

  • 這裡的 asis 為第一章 使用者設定 的使用者

  • 192.168.56.101 為我虛擬主機的 ip 位址,查詢 ip 位址可以先手動登入虛擬主機後,用 hostname -I 或是 ip addr show 指令查詢

完成後會提示你已經可以使用 ssh 連線

/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: "/home/kuaz/.ssh/id_ed25519.pub"
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed -- if you are prompted now it is to install the new keys

Number of key(s) added: 1

Now try logging into the machine, with:   "ssh -p '22' 'asis@192.168.56.101'"
and check to make sure that only the key(s) you wanted were added.

如果你是 Windows 的使用者也不用擔心有多複雜,一樣一行指令就能搞定,這裡我是參考(Christopher 2020)的教學,指令如下:

cat $env:USERPROFILE\.ssh\id_rsa.pub | ssh asis@192.168.56.101 "cat >> ~/.ssh/authorized_keys"
  • $env:USERPROFILE 為 Windows 內建環境變數,會根據現在的使用者變更。如果我的使用者名稱為 qaz855175b$env:USERPROFILE 就會產生 C:\Users\qaz855175b\ 的字串,當然你可以直接把這行指令的公鑰路徑替換為 C:\Users\qaz855175b\.ssh\id_rsa.pub

  • id_rsa.pub 為剛剛產生的公鑰名稱

  • asis 為 [user-configuration] 的預設使用者

  • 192.168.56.101 為我虛擬主機的 ip 位址,查詢 ip 位址可以先手動登入虛擬主機後,用 hostname -I 或是 ip addr show 指令查詢

其實 Linux 的 ssh-copy-id、和第一章安裝程式 ssh 環節的「由 Github 匯入(ssh-import-id-gh)」選項與這裡的 cat file >> ~/.ssh/authorized_keys 都是在做同一件事情,就是把公鑰貼到遠端伺服器的使用者家目錄的 authorized_keys 檔案裡面。

接著按 Enter↩︎,跳出輸入密碼提示,這裡輸入預設的使用者密碼 asis

asis@192.168.56.101's password:

輸入完後雖然沒有任何提示訊息,但其實已經可以使用 ssh 連線至遠端主機啦~

2.7.5 測試 SSH 連線

最後,使用 ssh 指令連接至遠端主機。

使用 ssh-keygen 產生的金鑰可以直接使用 ssh 指令連線。這裡介紹幾個常常與 ssh 一起出現的參數:

  • -v:verbose,顯示連接時更詳細的訊息,除錯時常用

  • -p:port,遠端伺服器的埠號

  • -i:手動指定私鑰位置

指令參數通常會在指令後面隨後出現,參數名稱前面前面會插入 -,而參數名稱後面有時會需要加入詳細的設定,有時不用。參數與參數之間用空格隔開,詳細指令的使用方法可以在 Linux 系統用 man <指令名稱> 查詢

假如我們要看連線的詳細訊息,且指定伺服器埠號為 60000 與指定私鑰檔案位置等等,組合起來就是:

ssh -v -p 60000 -i ~/.ssh/id_rsa asis@192.168.56.101

目前連線不需要加上任何參數,連線指令為:

ssh asis@192.168.56.101

一樣地,asis 是使用者名稱,而 192.168.56.101 是 OpenSSH 伺服器的 ip 位址,輸入完後按 Enter↩︎。

這邊打 yes 即可,確認連接目的地沒有錯之後,會把 fingerprint 寫入 ~/.ssh/known_hosts 中,以後不再詢問。

The authenticity of host '192.168.56.101 (192.168.56.101)' can't be established.
ECDSA key fingerprint is SHA256:/HoocrLXe63zycdlmkh/+U3RuUfkawNq/xA0gTJmqmM.
Are you sure you want to continue connecting (yes/no/[fingerprint])?

這裡不用指定私鑰的原因是因為,當你用 ssh 連線至目的地伺服器且你沒有指定認證檔案(私鑰)時,ssh 會在將金鑰一個一個拿去詢問這個金鑰可不可以使用。

連接成功!

Windows Terminal 下的 SSH 連接成功畫面

圖 2.5: Windows Terminal 下的 SSH 連接成功畫面

測試完確認沒問題在下個章節會介紹一些設定,使 OpenSSH 伺服器更加安全。

VirtualBox 的虛擬主機終端機畫面

圖 2.6: VirtualBox 的虛擬主機終端機畫面

2.7.6 OpenSSH 伺服器設定

  • 變更 SSH 伺服器預設的埠號
sudo vim /etc/ssh/sshd_config

#Port 22 取消註解,並把 22 改成其他介於 1-65535 之間的數字。這裡我使用 60000

/etc/ssh/sshd_config

[...]
Port 60000
  • 關閉密碼驗證

將 PasswordAuthentication(以密碼驗證)設為 no。使用 SSH 連線時,允許使用者密碼以輸入密碼驗證。

/etc/ssh/sshd_config

[...]
PasswordAuthentication no

當然如果密碼驗證為 no,且同時遺失 SSH 的 pair key 時,你就無法以 SSH 連線至遠端主機,需要使用其他方法補救。

  • 關閉遠端 root 登入

避免 root 登入可以使系統避免過大的權限暴露。

/etc/ssh/sshd_config

[...]
PermitRootLogin no
  • 限制能使用 SSH 連線的使用者

只允許特定的使用者使用 SSH 連線可大大降低風險。

/etc/ssh/sshd_config

[...]
AllowUsers asis
  • 關閉無密碼的使用者使用 SSH

將沒有密碼就可以登入的使用者撤銷 SSH 連線的權限。

/etc/ssh/sshd_config

[...]
PermitEmptyPasswords no

-t 參數可以測試 SSH 的設定是否有效,可以避免一些錯字造成的錯誤。

sudo sshd -t

將系統上的 SSH daemon 重新啟動,重新啟動 SSH 服務。

sudo systemctl restart sshd

確認 SSH 服務正常運行,沒有出現錯誤。

sudo systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
     Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enabled)
     Active: active (running) since Sun 2021-08-15 16:08:55 UTC; 19h ago
       Docs: man:sshd(8)
             man:sshd_config(5)
    Process: 850 ExecStartPre=/usr/sbin/sshd -t (code=exited, status=0/SUCCESS)
   Main PID: 893 (sshd)
      Tasks: 1 (limit: 4617)
     Memory: 5.4M
     CGroup: /system.slice/ssh.service
             └─893 sshd: /usr/sbin/sshd -D [listener] 0 of 10-100 startups

Aug 15 16:08:54 asis01 systemd[1]: Starting OpenBSD Secure Shell server...
Aug 15 16:08:55 asis01 sshd[893]: Server listening on 0.0.0.0 port 60000.
Aug 15 16:08:55 asis01 sshd[893]: Server listening on :: port 60000.
Aug 15 16:08:55 asis01 systemd[1]: Started OpenBSD Secure Shell server.

最後指令 exit 斷開連線,再重新測試 ssh 遠端連線至伺服器,使用公鑰與私鑰驗證登入。

ssh -p 60000 asis@192.168.56.101
Welcome to Ubuntu 22.04.3 LTS (GNU/Linux 5.15.0-79-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

  System information as of Tue Aug 15 06:04:51 AM UTC 2023

  System load:  0.173828125        Processes:               131
  Usage of /:   0.3% of 974.24GB   Users logged in:         0
  Memory usage: 13%                IPv4 address for enp0s3: 10.0.2.15
  Swap usage:   0%                 IPv4 address for enp0s8: 192.168.56.101

 * Strictly confined Kubernetes makes edge and IoT secure. Learn how MicroK8s
   just raised the bar for easy, resilient and secure K8s cluster deployment.

   https://ubuntu.com/engage/secure-kubernetes-at-the-edge

Expanded Security Maintenance for Applications is not enabled.

3 updates can be applied immediately.
To see these additional updates run: apt list --upgradable

Enable ESM Apps to receive additional future security updates.
See https://ubuntu.com/esm or run: sudo pro status


Last login: Tue Aug 15 06:04:51 2023 from 192.168.56.1

連線成功。

最後可以用 PowerShell 將設定檔寫入設定中

切換資料夾至使用者資料夾中的 .ssh

cd $env:USERPROFILE\.ssh

使用筆記本編輯設定

notepad config.

將下列設定檔加入設定。

Host vm
    Hostname 192.168.56.101
    User asis
    Port 60000

接下來就可以用別名 vm 進行連線了

ssh vm