---
# System prepended metadata

title: 剩下的基礎指令 + ssh

---

# 剩下的基礎指令 + ssh
[TOC]

* 遠端連線
    * 當需要更好的運算能力
    * 管理主機更加方便
    * 遠端連線伺服器，使用服務

* SSH
    - **S**ecure **Sh**ell 安全外殼協定
    - 解決 telnet 不安全的問題
    - 走port 22
    - 使用非對稱加密進行身份驗證，確保語法安全：使用者在本地生成一對公私鑰（私鑰保密，公鑰上傳至伺服器），連線時伺服器以公鑰驗證私鑰持有者身份，無需傳送密碼，有效避免明文洩露風險。

### 不同加密方式
* 對稱式加密
  - 雙方使用 **同一把密鑰** 進行加解密 
  - 優點：速度快，適合大量資料傳輸 
  - 缺點：需要事先安全交換密鑰 

* 非對稱式加密
  - 使用 **一對鑰匙**：公鑰 (Public Key) 與 私鑰 (Private Key) 
  - 公鑰：任何人都能用來加密 
  - 私鑰：只有持有者能解密 
  - 優點：不用事先交換密鑰，就能安全建立連線 
  - 常用於金鑰交換與身份驗證
    

數位簽章

假如今天A想傳訊息給B，那會先將原文訊息做雜湊函數得出一串雜湊值，然後用A的私鑰做加密將它變成數位簽章，此時原文訊息則可以用B的公鑰加密成密文，A再把密文以及數位簽章一併傳送給B。

而B收到以後，用自己的私鑰解開密文獲得原文訊息後，再用相同的雜湊函數產生雜湊值，當與用A的公鑰來解開數位簽章的雜湊值相符，就可以確定是A本人傳送的。
![image](https://hackmd.io/_uploads/ryabXB8hxx.png)

Hash 雜湊函式
>$$ H(x) = x \mod B $$

ssh連線
1. TCP連線
2. 版本交換
3. client驗證server的host public key
4. 透過非對稱金鑰演算法交換金鑰，產生session key並用它進行對稱式加密，開始在加密通道中傳訊
* ssh 不是對稱式加密也不是非對稱式加密

### 基礎操作
安裝
* 更新軟體的最新資訊及列表: `sudo apt update`
* 安裝 server 端套件: `sudo apt install openssh-server`
* 同時安裝 server 及 client: `sudo apt install ssh`

`apt update `：根據系統列表抓取來源，更新列表本身

`apt upgrade`：把已安裝軟體做更新、升級
`` ：過去自動安裝，是否更改設定檔

### 確認 server 狀態
* 查看<服務>狀態
    * `sudo systemctl status <服務>`
        e.g. ssh `sudo systemctl status ssh`
* 查看 ssh 佔用 port
    * `sudo ss -ltpn`
        * `-l`: 列出傾聽狀態（listening）的 sockets(可當作聆聽正在使用之服務)
        * `-t`: 只列出 TCP 的 sockets
        * `-p`: 顯示使用 sockets 的程式資訊
        * `-n`: 不要嘗試把 port 號解析成服務名稱

* http 占用 port 80; 
https 占用 port 443

### 開啟關閉與重啟 server
在做任何設定黨服務的時候都要記得去開始

`sudo systemctl start ssh`：開始
`sudo systemctl stop ssh`：停止
`sudo systemctl restart ssh`：重新啟動；關掉再打開

### 由 client 登入
* 登入本機
    * `ssh localhost` 
    * `ssh 127.0.0.1`
    * `ssh [username]@127.0.0.1`
        * 使用 `ssh [username]@127.0.0.1` 可以通過 SSH 連接到本地電腦。
        * `127.0.0.1` 是本地回送地址，通常等同於 `localhost`（可在 `/etc/hosts` 檔案中確認）。
        * `127.0.0.1/8` 是保留的 IP 範圍，發送到這個地址的資料封包不會離開本機。
        * `localhost` 是一個頂級域名，禁止任何網域註冊使用。

* `ssh [username]@[hostname]`
ssh 連線到指定server
    * `-p [port num]` 改server port號，在大多數情況下不建議改port號，並不會提升安全性，也會造成管理困難
    * `-v` 偵錯模式連線，建議連線時加上此option

* `ssh [username]@[hostname] '[cmd]'`
執行單行指令
    * `-f` 背景執行
    
- `passwd`：更改密碼
    - 用法：`sudo passwd user`
    - user 是對應的使用者名字
- 退出連線
    - `exit`
    - `logout`
    - `Ctrl+D`

* 產生公/私鑰金鑰對
    `ssh-keygen -t ed25519`

* 私鑰會存在 `~/.ssh/id_ed25519` -> 自己留著，不能給別人的

* 公鑰會存在 `~/.ssh/id_ed25519.pub` -> 傳給別人的


 



| `RSA`                                                                        |  `ed25519`   |
| ---------------------------------------------------------------------------- | --- |
| 為三個人名的縮寫，相容性最好，支援稍舊的版本，1024-16384 bits，預設2048 bits   |  生成金鑰更快、安全性更好，256 bits   |
| 建立在「大整數分解困難」上，為安全性只能一直加大鑰匙長度 |   建立在「橢圓曲線離散對數問題」  |

- 把剛剛的公鑰放到遠端 server
```
ssh-copy-id -i ~/.ssh/id_ed25519.pub s${學號}@moli.lsa.tw
```
> @bs10081 :應該在每台電腦上生成 SSH Key，而不是生成一份以後放到每一台電腦(1Password 這種密碼管理器除外)


## Forward Agent
![image](https://hackmd.io/_uploads/BJTVPozngg.png)

範例狀況：員工(User) severA(網站)、severB(後端)為公司
* severA不具備金鑰，為了資訊安全也關閉密碼方式登入severB
* severB為後端伺服器禁止外部IP連入
* severB具有User的公鑰
* 實例：員工居家辦公要透過severA連入severB獲取資料

流程：
1. User本地端有一個ssh-agent內含forwarding 功能，可不透過網路傳送金鑰讓遠端sever使用地端金鑰進行驗證
2. User連上severA例如ssh -A seal@192.1168.0.1(加上A開啟agent forwarding)
3. 要再繼續往後端severB連時，會自動透過SSH通道，用本機金鑰遠端認證
4. User agent幫忙完成簽章後傳回結果

關鍵點：
- 私鑰 **永遠不會離開本地電腦**。
- 遠端機器只能透過 SSH 通道「借用」你的 agent 做簽章。
- 如果 serverA 被入侵，攻擊者可能利用已建立的 SSH 通道來嘗試連入 serverB。
> @bs10081: 都沒人寫共筆，你們期中考要完蛋了 ：）

> 某某好心人：LSA server 地址是 `ssh -v s${學號}@moli.lsa.tw`

> @bs10081: 👆 `${}` 代表你需要自己修改這個地方變成你自己的學號，而不是寫 `ssh -v s${學號}@moli.lsa.tw`，例如 `ssh -v s110213027@moli.lsa.tw`，實務上，只要見到 `${}`、`<username>`、`example.com`、`John Doe` 都是「記得要改成自己的」的意思。


