# SSH 教學:SSH 與 SCP
最近因為在工作上、學校經常用到 **SSH 連線**這個技術,因此想說來寫一篇使用使用 SSH 連線遠端主機的教學。順道教學一下如何利用 **SCP** 來將檔案在 client 端與 server 端互相傳遞。
> ps. 本教學將專注於初階技術面,不探討過於理論的知識,並且技術面只介紹 client 端的操作。本文章也會隨著研究慢慢深入
## SSH 是什麼
就如同大多數技術文章一樣,開頭都會不免俗得介紹一下該技術。
**SSH,全名 Secure Shell**,是一種能夠安全進行遠端連線的協定。使用 SSH 可以讓你連接遠端主機,並可在遠端主機與本地主機間傳遞檔案。
此外,由於傳遞過程有經過加密,因此相較於其他檔案傳輸協定(**Telnet**)而言較為安全。

> 圖片來源:*What is SSH Protocol?*.Wallarm.https://www.wallarm.com/what/what-is-ssh-protocol
## SSH 連線
### 檢查環境
在進行 SSH 連線前,我們得先知道自己所在的環境是否支援 SSH 連線。雖然大多數作業系統皆支持 SSH client 端連線,但我們可以透過輸入以下指令來確認是否有安裝 SSH。
```shell
ssh
```
如果出現**不是內部或外部命令**這種報錯訊息的話,以 Window 10/11 為例,需要透過安裝 [OpenSSH](https://learn.microsoft.com/en-us/windows-server/administration/openssh/openssh_install_firstuse?tabs=gui&pivots=windows-server-2025) 是否啟用。
### 正式連線
一般我們在連線前,必須知道以下資訊:
- **遠端主機位址(Host)**:可以是 ip 位址,例如 `140.122.1.23`;或者是 Domain,例如 `my-server.com`
- **使用者名稱(Username)**:在遠端 server 允許的使用者名稱
- **使用者密碼(password)**:第一次連線時,需要密碼才能進行連線,之後可以透過其他方式免密碼登錄
- **Port**:一般預設為 `22`,如果你的遠端 server 有特定的 port,需要額外知道
知道以上資訊後,輸入下方這條指令後即可連線:
```shell
ssh username@host
```
如果需要指定 port 的話請輸入:
```shell
ssh -p port username@host
```
之後可能會要求輸入密碼、fingerprint 確認。一律依照 terminal 指示去做就好。 以上流程都順利執行完成後,即可完成連線。
### 關閉連線
執行以下指令即可關閉 SSH 連線:
```shell
exit
```
## 免密碼連線
如果每次都需要密碼才能連線的話,是不是很麻煩呢?有一種方法可以透過 **rsa 加密金鑰**來進行 SSH 連線,這種方法就可以讓相同 client 端不透過密碼就能夠連線至 server 端,以下是操作步驟。
首先我們必須輸入以下指令,生成 **rsa 金鑰**。
```shell
ssh-keygen -t rsa
```
輸入完成後,下面應該會出現一堆讓你填入的東西,這邊我們都不填入,即可使用預設值創建 rsa 金鑰。出現下面畫面後,就完成 rsa 金鑰生成了。
```shell
Your identification has been saved in /home/username/.ssh/id_rsa_ubuntu.
Your public key has been saved in /home/username/.ssh/id_rsa_ubuntu.pub.
The key fingerprint is:
SHA256:nNnQckFbuegUs4WD3y+7YqwCaDhfUlX2J17jxF7X3FU xenby@demo.com
The key's randomart image is:
+---[RSA 2048]----+
| .o++ .. E|
| . *o+. ..|
| . = *+ o ..|
| . . Ooo+ * +|
| . o Soo..B o.|
|o + o . ..o |
| + o . . . . |
| . . + o |
| ..o .o. |
+----[SHA256]-----+
```
如果之前沒有指定路徑的話,rsa 私鑰與公鑰都會放在 `.ssh` 資料夾底下。其中私鑰為 `.ssh/id_rsa`,用來辨識身分,需要妥善保管不能被竊取;公鑰為 `.ssh/id_rsa.pub`,用來放在遠端 server 上,進行連線時會和私鑰配對。
```shell
.ssh
├── id_rsa
├── id_rsa.pub
└── ...
```
我們可以透過下方指令將 `id_rsa.pub` 放到遠端:
```shell
cat .ssh/id_rsa.pub
ssh username@host 'cat >> .ssh/authorized_keys'
```
這樣子就可以免密碼連線該遠端主機了。
## 設定連線資料
如果每次連線,都需要輸入 username 與 host 的話,實在是很麻煩。因此,我們可以透過在本地端設定連線資料的方式,先將連線資料填入後,直接輸入一個主機名字就可以連線了。
首先我們前往 `~/.ssh/config` 這個檔案,如果沒有可以直接創一個。之後在 config 中填入以下資訊。
```shell
Host A
HostName 11.111.111.11
User B
Port C
```
其中 **Host** 是指這個遠端主機在你的本地代表的名字,可以自己取,之後也會用他來代表整個遠端主機。
設定完成後,我們只要輸入以下指令就可以連線了:
```shell
ssh A
```
## SCP
**SCP** 可以用來支援 Linux 本地端與遠端間的資料複製。利用 SSH 安全加密的方式將檔案從遠端傳到本地端,或是本地端上傳到遠端。同樣的在 mac OS 與 Windows 也可以進行。
### 複製一個檔案
今天如果想從本地傳一個檔案到遠端,可以輸入以下指令:
```shell
scp <local_path> <username@host>:<host_path>
```
反過來如果想要從雲端傳一個檔案到本地的話,可以這樣輸入:
```shell
scp <username@host>:<host_path> <local_path>
```
這樣就可以完成檔案複製了
### 複製一個目錄
如果我們想要複製一個目錄到雲端的話,我們可以透過加上 `-r` 來進行整個目錄的複製,反之亦然。
```shell
scp -r <local_path> <username@host>:<host_path>
```
### 資料壓縮
:::warning
如果想要壓縮傳輸一個資料夾的話,`-r` 與 `-C` 都要加,順序不拘。
:::
如果不想占用太多頻寬,我們可以透過 `-C` 來先將檔案壓縮後再傳上去雲端。
```shell
scp -C <local_path> <username@host>:<host_path>
```
## 結語
以上就是本教學的內容,希望對你在未來的工作有幫助。
## 參考資料
*SSH login without password*. http://www.linuxproblem.org/art_9.html