3,044 瀏覽數

SSH (Secure SHell)

SSH 主要是用來取代 Telnet 這種以明碼為傳遞基礎的遠端登入服務,我們先來看看要如何連線到 SSH Server.
測試環境為

  • SSH Client: Mac OS – IP : 172.16.15.1
  • SSH Server: Ubuntu 16.04 Desktop -IP : 172.16.15.221

Mac OS 10 (SSH Client) 連線到 Ubuntu 16.04 (SSH Server)

SSH Server 安裝

安裝好的 Ubuntu Desktop 是不允許透過 SSH 連進來的,因為預設是沒有安裝該服務,安裝也很簡單,直接安裝套件 openssh-server

root@ubuntu:~# apt-get install openssh-server
..
root@ubuntu:~# systemctl status sshd
● ssh.service - OpenBSD Secure Shell server
   Loaded: loaded (/lib/systemd/system/ssh.service; enabled; vendor preset: enab
   Active: active (running) since Fri 2016-12-23 00:38:37 PST; 3min 33s ago
  Process: 1216 ExecReload=/bin/kill -HUP $MAINPID (code=exited, status=0/SUCCES
 Main PID: 844 (sshd)
   CGroup: /system.slice/ssh.service
           └─844 /usr/sbin/sshd -D

SSH Linux Client (基於密碼的安全驗證)

不用修改 SSH server ,SSH Clients 端一開始就可以使用.

appledeAir:~ ben$ ssh ben@172.16.15.221
The authenticity of host '172.16.15.221 (172.16.15.221)' can't be established.
ECDSA key fingerprint is SHA256:qRW5nzrgHLRzNj37o1EJtOt8/+2/o/c87aSc5JcquGE.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added '172.16.15.221' (ECDSA) to the list of known hosts.
ben@172.16.15.221's password: 
Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-47-generic x86_64)

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

8 packages can be updated.
0 updates are security updates.

*** System restart required ***
Last login: Wed Dec 21 17:40:31 2016 from 172.16.15.1
ben@ubuntu:~$ 

感覺很簡單,但實際上已經經過一連串的加密.
SSH 採用 RSA , DSA 認證步驟如下:

  1. SSH Server 會把他的公開金鑰提供給 SSH Client 來作加密使用.
  2. SSH 伺服器會檢查 SSH Client 指定的使用者是否有儲存公開金鑰在 $HOME/.ssh/authorized_key 檔案中.
  3. 沒有 – 基於密碼的安全驗證 (使用帳號和密碼登入).
    1. 如果沒有 SSH Server 會提示使用者輸入使用者密碼.
  4. – 基於金鑰的安全驗證.
    1. 有的話 SSH Server 會請求 SSH Client 作身份驗證.
    2. SSH Client 會檢查自己的 $HOME/.ssh 目錄下,看看你是否擁有私鑰 (名稱 id_dsa)
    3. 如果私鑰存在,SSH 會提示你輸入此私鑰的通行證,接下來會使用這私鑰來建立簽章並傳給 SSH Server.
    4. 如果 SSH Server 用 SSH Client 公鑰驗證,驗證成功就不需要使用者輸入密碼了.

我們剛剛的登入就是採用基於密碼的安全驗證 (使用帳號和密碼登入到遠端 SSH Server 主機),詳細說明如下.
SSH Client 第一次登入 SSH server 沒有辦法建立連線.Server 會把公開金鑰 (OpenSSH 在安裝時會產生 DSA,ECDSA,ED25519,RSA 加密的主機金鑰) 提供給 Client 來作加密使用.SSH client 會詢問使用者,這是否你要連線的 Server ,yes 就接受這個尚未被信任的公開金鑰.

剛剛使用的是 ECDSA key (Server public Key),因為怕這個 Key 被竄改所以用了 fingerprint SHA256 (One Way Hashes) 的方式來確定資料是沒有被改過的.

appledeAir:~ ben$ ssh ben@172.16.15.221
The authenticity of host '172.16.15.221 (172.16.15.221)' can't be established.
ECDSA key fingerprint is SHA256:qRW5nzrgHLRzNj37o1EJtOt8/+2/o/c87aSc5JcquGE.
Are you sure you want to continue connecting (yes/no)? yes

OpenSSH Server 產生的金鑰位於路徑 /etc/ssh/ ,金鑰種類有 DSA,ECDSA,ED25519,RSA ,金鑰都有 public 與 private Key.

root@ubuntu:~# ll /etc/ssh/ssh_host*
-rw------- 1 root root  668 Nov 16 18:36 /etc/ssh/ssh_host_dsa_key
-rw-r--r-- 1 root root  601 Nov 16 18:36 /etc/ssh/ssh_host_dsa_key.pub
-rw------- 1 root root  227 Nov 16 18:36 /etc/ssh/ssh_host_ecdsa_key
-rw-r--r-- 1 root root  173 Nov 16 18:36 /etc/ssh/ssh_host_ecdsa_key.pub
-rw------- 1 root root  399 Nov 16 18:36 /etc/ssh/ssh_host_ed25519_key
-rw-r--r-- 1 root root   93 Nov 16 18:36 /etc/ssh/ssh_host_ed25519_key.pub
-rw------- 1 root root 1679 Nov 16 18:36 /etc/ssh/ssh_host_rsa_key
-rw-r--r-- 1 root root  393 Nov 16 18:36 /etc/ssh/ssh_host_rsa_key.pub

剛剛選擇 yes 則表示 SSH client 接受 SSH server 的公開金鑰並且存放在使用者家目錄 .ssh/known_hosts 下,我們可以看到 Mac OS 10 把這個 ECDSA public Key 儲存下來了,未來再登入到同一台 SSH Server 就不會再詢問是否接受 Server Public Key 的問題了.

appledeAir:~ ben$ ls .ssh/*
.ssh/known_hosts
appledeAir:~ ben$ cat .ssh/known_hosts 
172.16.15.221 ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNPYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBLMw58hQS4QSgarOjRfyVoLp/RAaBGz+yR87wXj4aeFIjpvPw8x9RW/y6R7A0JUUyvasu19K+7ukxwpVFJooD34=

有了這 SSH Server Public Key 就可以繼續後面一連串的安全連線的機制.

SSH Client 接受 SSH Server 公開金鑰之後,SSH Client 自己也會隨機產生一支的公私鑰 (每次連線都會產生新的金鑰),並傳自己的公開金鑰給 SSH server.

這樣彼此都有對方的公開金鑰就可以開始安全性的傳輸,之後會協調出一把針對資料加密的 session 金鑰 3DES(Triple-DES),blowfish 或 IDEA 等對稱加密 (symmetric encryption) 的鑰匙來加密.

關於 Asymmetric Encryption 非對稱式加密的方式如下:

  1. 接收端 (SSH Server)
    會產生兩把鑰匙 (Public / Private Key), Public Key (P:公開金鑰 ) 會發佈給其他人來使用,而 Private Key (S:私有金鑰) 則自己保存.
  2. 傳送端 (SSH Client)
    傳送端會使用 (P) 將資訊 M 來加密, 並將經過加密的資料 P(M) 傳送出去
  3. 接收端 (SSH Server)
    接收端就可以用私鑰來解密 M=S(P(M))

Client 是如何將 “session 金鑰 (對稱加密 symmetric encryption)” 傳送至 Server (對稱加密使用同一把鑰匙加解密,再網路上傳送時有可能被擷取),方法就是使用非對稱式加密的方式來傳送,其資料就是 session 金鑰.

為何不使用公開金鑰來加密,第一因為非對稱加密的演算法很消耗 CPU 的資源,第二 session 金鑰是為了特定的 session (使用者每次建立的連線) 而建立的,當 session 關閉後就不會再用了.對入侵者而言 session 金鑰所需功夫較多 (因為每位使用者 session 金鑰皆不同).

SSH protocol version 2
與 version 1 不同的是,在 version 2 當中將不再產生公開主機金鑰了,所以,當 Client 端連線到 Server 端時,兩者將藉由 Diffie-Hellman key(非對稱式加密的一種) 的演算方式來產生一個分享的 Key ,之後兩者將藉由類似 Blowfish(對稱式加密的一種) 的演算方式進行同步解密的動作!

每一個 sshd 都提供這兩個版本的連線,而決定這兩種模式連線的,就必需要在 client 端連線時選擇連線的模式才能確認。目前預設情況下,會自動使用 version 2 的連線模式喔!而由於我們的連線資料中,經過了這個 Public 與 Private Key 的加密、解密動作,所以在中間的傳送過程中,當然就比較安全的多

SSH Windows Client

在 Linux 底下已經有 ssh 了,那麼如果在 Windows 客戶端下呢?該怎麼辦,這個可以直接使用 putty (只要 putty.exe 這支程式就夠了) 這種類型的連線軟體呢,他也是免費的軟體喔!取得的方式可以參考底下的網站:
http://sourceforge.net/projects/leputty

直接在 Windows 底下執行,執行的圖示有點像底下這樣
putty01
這樣就可以連上你的 SSH Server 了.

SSH Linux Client (基於金鑰的安全驗證)

SSH 提供兩種方式的安全驗證

  1. 基於密碼的安全驗證 – 剛剛使用的就是使用帳號和密碼登入到遠端 SSH Server 主機.
  2. 基於金鑰的安全驗證 ( RSA 與 DSA 認證) – 接下來要說明的.

使用者身份認證
Server 預設是會嘗試使用 RSA (SSH V.1) 或 DSA (SSH V.2) 憑證 (金鑰對,非對稱式加密)來對客戶端來做驗證,如果使用者擁有 server 認可的憑證,使用者需輸入憑證的祕密金鑰通行碼,如果成功 SSH client 與 Server 會使用憑證來完成 challenge-response 驗證.
如果 RSA/DSA 驗證失敗,或一開始就沒有客戶端憑證,則遠端伺服器會提示使用者輸入正確的標準 Unix 使用者名稱/密碼組合.要記住客戶端與伺服器間已經建立了加密的 session 因此使用者名稱 / 密碼的組合,雖然比憑證為基礎的驗證容易破壞,但至少在傳送之前加密過了(session 金鑰).

Asymmetric Encryption 非對稱式加密 ( 用於數位簽證 Digital Signatures )
主要用在身份的確認,方法類似 Asymmetric Encryption 一樣會使用兩把鑰匙 (公與私 Public / Private Key), 但運作方式是由 傳送端 產生兩把鑰匙 (Public/Private Key),一樣 Private key 會當成加密用而 Public key 就會當解密用,方法如下.

  • 傳送端 – 產生兩把鑰匙 (Public/Private Key), Public Key(P) 會發佈給其他人來使用,而 Private Key (S) 則自己保存.傳送端使用自己產生的 Private key (S) 將資訊 M 來加密, 並將經過加密的資料 S(M) 傳送出去.
  • 接收端 – 接收端就可以用傳送者的公鑰來解密 M=P(S(M)) ;這種方式的接收者可以確定傳送者,但傳送者無法得知接收者是否由其他人冒充.所以產生下面這兩種方法.

我們可以透過建立 Public Key 而不需輸入密碼.實作上的步驟如下 :

  • Client 端
    首先,先在 Client 上面建立 Public Key 跟 Private Key 這兩把鑰匙,利用的指令為 ssh-keygen 這個命令:

    appledeAir:~ ben$ ssh-keygen -t rsa
    Generating public/private rsa key pair.
    Enter file in which to save the key (/Users/ben/.ssh/id_rsa): 
    Enter passphrase (empty for no passphrase): 
    Enter same passphrase again: 
    Your identification has been saved in /Users/ben/.ssh/id_rsa.
    Your public key has been saved in /Users/ben/.ssh/id_rsa.pub.
    The key fingerprint is:
    SHA256:9yvVc6q/uROmYtY39PcWNIhuADHa6TMsrf6QpmFoUh4 ben@appledeAir
    The key's randomart image is:
    +---[RSA 2048]----+
    |       o.        |
    |      o.o        |
    |     . o.   . .  |
    |      +  . . . o |
    |  E  . *S +  .. .|
    | o..  + o. +. *..|
    |.o.o =    .o.+ *.|
    |o . = .   = o.=.+|
    |   . ... o oo+=*+|
    +----[SHA256]-----+
    appledeAir:~ ben$ ls .ssh/*
    .ssh/id_rsa		.ssh/id_rsa.pub		.ssh/known_hosts
    

    上面產生的 key 為 RSA ,你也可以指定為 DSA ,產生的 key 存在 $HOME/.ssh 中 (id_rsa 為私鑰, id_rsa.pub 為公鑰),passphrase 主要是保護私鑰 (你需要一串密碼來解開私鑰),你也可以不設.

    要這把Client 的 Public Key 放在任何一個你想要用來登入的主機的 Server 端 User 的家目錄內 (請先確認有 ~/.ssh 目錄).

    appledeAir:~ ben$ scp .ssh/id_rsa.pub 172.16.15.222:/home/ben/.ssh/
    ben@172.16.15.222's password: 
    id_rsa.pub                                    100%  396   790.8KB/s   00:00
    
  • server 端
    匯入剛才 client 端產生的公鑰至 $HOME/.ssh/ 裏面的認證檔案 authorized_keys 即可完成

    ben@ubuntu:~$ cd ~/.ssh
    ben@ubuntu:~/.ssh$ cat id_rsa.pub >> authorized_keys
    ben@ubuntu:~/.ssh$ cat authorized_keys
    ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5wZYPD/mBs+9O9CrUxdg9kpOus24VrMuNncdt4BRc4iF5npV90HYe5j/y3IG6+2MRbAb2edyf/FUcaJHN/V+iZSRZyufzqyAT2rv9T0eB2+wpmYCUQzqZscJP2uLK8jMhezKWS0l7X5CgJf+d17VooS6CADR9MyTbku3upKp5yEnsCfB+pBLGdrqCUTnGHPfJcLTBIvuMriz/kae0Y7qnjHRNbw7YWR9oKdWjKYKlznnBmH6VYFcgv/jSXbRbdZjKNSXIm2xIj6TIIJmo6sWhptcGohi467ODyrzCDioXD1MsYx6ImTMcY5mzL2RDePAW7CM4gWIMaIxDeL5e10SX ben@appledeAir
    

    或是透過 ssh-copy-id user@host 來產生 authorized_keys

  • Client 端
    下次登入就不需要使用者帳號密碼了,但是如果你有設定私鑰的 passphrase 這時還是需要私鑰的 passphrase .

    appledeAir:~ ben$ ssh ben@172.16.15.222
    Enter passphrase for key '/Users/ben/.ssh/id_rsa': 
    Welcome to Ubuntu 16.04.1 LTS (GNU/Linux 4.4.0-57-generic x86_64)
    
     * Documentation:  https://help.ubuntu.com
     * Management:     https://landscape.canonical.com
     * Support:        https://ubuntu.com/advantage
    
    8 packages can be updated.
    0 updates are security updates.
    
    Last login: Fri Dec 23 01:14:55 2016 from 172.16.15.1
    ben@ubuntu:~$ 
    

SSH 的設定檔

[root@benjr ~]# vi /etc/ssh/sshd_config

請參考鳥哥的網站 http://linux.vbird.org/linux_server/0310telnetssh.php#ssh_sshdconfig

安全性的設定

SSH 雖然是比較安全的,但是沒有人能保證 SSH 就不會有漏洞,所以你還是能使用些防護機制來保護你的 SSH.根據 網路存取安全機制 這一篇.防護機制可以包括以下兩個.
防火牆 (iptables) :
由於 ssh 這個服務是開啟在 port 22 ,所以你可以使用 ipchains 或 iptables 來開放一些你允許的 IP 以 port 22 的進入!
TCP Wrappers:
SSH 引用 libwrap.a library,則會受到 TcpWrapper ( /etc/host.allow , /etc/host.deny) 的控管的控管. 關於 TCP Wrapper 請參考下列的網頁 TCP Wrapper

錯誤訊息

使用 SSH 常見的錯誤訊息.
這個發生在妳的 SSH Server 公鑰與上次登入的不一樣,有可能是妳的 Server 換了.只要你確認登入的 SSH Server 沒錯.可以修改 known_hosts 即可以解決.

[root@benjr ~]# scp -r msgs 192.8.1.1:/root
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
@ WARNING: REMOTE HOST IDENTIFICATION HAS CHANGED! @
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
IT IS POSSIBLE THAT SOMEONE IS DOING SOMETHING NASTY!
Someone could be eavesdropping on you right now (man-in-the-middle attack)!
It is also possible that the RSA host key has just been changed.
The fingerprint for the RSA key sent by the remote host is
85:65:da:e4:9d:02:76:50:a8:3e:31:f9:df:8a:8e:62.
Please contact your system administrator.
Add correct host key in /root/.ssh/known_hosts to get rid of this message.
Offending key in /root/.ssh/known_hosts:1
RSA host key for 192.8.1.1 has changed and you have requested strict checking.
Host key verification failed.
lost connection

只要移除使用者的 known_hosts 即可,如 root 的設定檔位於 /root/.ssh/known_hosts ,不過這樣其他的 SSH 下次登入還要再同意一次,建議只刪除檔案有衝突的部分.

[root@benjr ~]# rm /root/.ssh/known_hosts
rm: remove regular file `/root/.ssh/known_hosts’? y
[root@benjr ~]# scp -r msgs 192.8.1.1:/root
The authenticity of host ’192.8.1.1 (192.8.1.1)’ can’t be established.
RSA key fingerprint is 85:65:da:e4:9d:02:76:50:a8:3e:31:f9:df:8a:8e:62.
Are you sure you want to continue connecting (yes/no)? yes
Warning: Permanently added ’192.8.1.1′ (RSA) to the list of known hosts.
root@192.8.1.1′s password:

5 Replies to “SSH (Secure SHell)”

  1. 自動參照通知: SSH – Remote Host identification has changed – Benjr.tw

  2. 自動參照通知: Networking | Benjr.tw

  3. 自動參照通知: 安全性 | Benjr.tw

  4. 自動參照通知: WSCP – windows Secure copy | Benjr.tw

  5. 自動參照通知: Amazon 雲端服務(二) – EC2 | Benjr.tw

發表迴響