SSH 基本概念
SSH 英文全稱是secure shell,字面意思:安全的shell。
SSH協議由IETF(Internet Engineering Task Force)的Network Working Group所制定,建立在應用層和傳輸層基礎上相對可靠,專爲遠程登錄會話和其他網絡服務提供安全性的協議。
說其是Secure的很重要一個原因是ssh會對遠程登陸時的認證信息和遠程執行的命令進行加密傳輸。而傳統的網絡服務程序如ftp、telnet、pop、rlogin、rexec等都是在網絡上用明文傳送口令和數據,這樣就容易受到網絡上別有用心的人攻擊(例如“中間人”)。而對SSH對口令及數據加密傳輸則可以有效防止這種攻擊。
功能上它既可以代替telnet,又可以爲ftp、pop、甚至ppp提供一個安全的“通道”。
ssh協議目前有SSH1和SSH2,SSH2協議兼容SSH1。
目前實現SSH1和SSH2協議的主要軟件有OpenSSH和SSH Communications 軟件。
OpenSSH是一款免費開源的SSH軟件,而SSH Communications見分則是一款商業軟件並且收費的。一般在類unix系統上使用的是OpenSSH。
SSH 層次結構
- 傳輸層協議 [SSH-TRANS]
提供服務器認證,數據機密性,信息完整性 等的支持;
- 用戶認證協議 [SSH-AUTH]
爲服務器提供客戶端的身份鑑別;
- 連接協議 [SSH-CONN]
將加密的信息隧道複用成若干個邏輯通道,
對於這部分的詳細內容請閱讀:SSH協議詳解 http://airekans.github.io/protocol/2012/06/28/ssh-explained/
相關的工具命令:
Sftp 使用了加密傳輸方式的遠程傳輸工具,使用命令與ftp基本一樣,這種傳輸方式使用了加密/解密技術,所以傳輸效率比普通的FTP要低,適合網絡安全性要求更高的情況使用。
Scp 非交互式sftp-server的客戶端,用來向服務器上傳/下載文件
Sshfs 遠程目錄掛載工具,非常方便實用,使用方法參見http://www.programfish.com/blog/?p=145
SSH 認證方式
SSH客戶端的身份認證中提供三種方式:
- password(基於口令的安全驗證)
- public key(基於密匙的安全驗證)
- Hostbased驗證
{SSH2.0還提供了 password-publickey 認證(方式一和二都進行)和 any 認證(進行方式一或二中的一種)}
其中最常用的是password驗證及public key驗證。
Password驗證就是在你請求連接到遠程主機的時候要求輸入遠程主機上的用戶口令並加密傳輸到遠程主機上進行驗證。
而public key驗證不需要在網絡上傳送口令,它依賴於在本地創建的一對密鑰(公鑰和私鑰)進行驗證。
以下會以實例操作介紹兩種認證方式(使用開源的openSSH操作):
Password認證:
- 指定ip連接:
lfly@linux-oj9e:~> ssh 172.17.0.3
- 指定的主機名連接:
lfly@linux-oj9e:~> ssh www.programfish.com
- 指定登陸用戶名(上面沒有指定則使用當前用戶名):
lfly@linux-oj9e:~> ssh [email protected]
lfly@linux-oj9e:~> ssh [email protected]
如果是第一次嘗試連接到當前指定的遠程主機,則會出現如下提示:
lfly@linux-oj9e:~> ssh 172.17.0.3
The authenticity of host ‘172.17.0.3 (172.17.0.3)’ can’t be established. ECDSA key fingerprint is 2a:d9:31:44:04:08:ed:ff:2e:0a:3d:31:53:65:3b:f3. Are you sure you want to continue connecting (yes/no)?
這裏由於是本地首先連接到該遠程主機(172.17.0.3),ssh會提示你是否要信任這個主機,這裏需要你鍵入yes回車,選擇了信任這臺主機後ssh會把這臺主機上的公鑰(public key)記錄在~/.ssh/known_hosts這個文件下(.ssh是你家目錄下的一個隱藏目錄)。
這裏其中一個公鑰是這樣的:
|1|w2w2Qcl7o5Mi4Iwcg613O+16I4A=|NpE0Zzu5NsgZ3DEpYLgNfzwhcR4= ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBARhzN4tb3VaHAdPJBi/H+rW/ARafC0CSJE4QrpepOIv55T+P+AV9pMsPpug0juAW/E3V929p+KhtKqUrkMP+SU=
這樣下一次你再嘗試連接這個IP地址的遠程主機時ssh會拉取它的公鑰然後與known_hosts文件裏的這個ip的公鑰作對比,如果對比吻合,則順利跳過這步。如果對比不吻合,則ssh會提示你遠程主機身份證明(公鑰)已經改變,這次連接可能正在受到中間人的攻擊(man-in-the-middle attack)。
提示如下:
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @ 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 a host key has just been changed. The fingerprint for the ECDSA key sent by the remote host is 70:60:25:72:8f:96:f6:cd:25:16:80:30:30:58:de:ea. Please contact your system administrator. Add correct host key in /home/lfly/.ssh/known_hosts to get rid of this message. Offending ECDSA key in /home/lfly/.ssh/known_hosts:1 You can use following command to remove all keys for this IP: ssh-keygen -R 172.17.0.3 -f /home/lfly/.ssh/known_hosts ECDSA host key for 172.17.0.3 has changed and you have requested strict checking. Host key verification failed.
這種情況如果不是中間人攻擊則很可能是因爲遠程主機上的操作系統更換了導致了ssh公鑰改變了。
這樣的話解決方法就很明瞭:手動刪掉known_hosts裏面的相應或全部內容後再嘗試連接該遠程主機。
- 使用別名認證(免去記遠程ip的麻煩)
在~/.ssh下的config文件(沒有則創建)里加入如下格式的內容:
Host cg
HostName 172.17.0.3
User lfly
這樣的話我就把上面我的遠程主機設置了一個別名爲cg 。
下次就可以這樣連接到該主機:
lfly@linux-oj9e:~> ssh cg
上面的命令等價於: lfly@linux-oj9e:~> ssh [email protected]
如果要設置多個遠程主機的別名,則添加多個以上的三行爲一組的內容進config文件即可。
public key認證(免密碼認證)
過程:
- 先在本地創建一對密鑰(公鑰和私鑰),並把公匙放在需要訪問的服務器上;
- 客戶端向遠程服務器發出請求用你的公鑰認證;
- 服務器收到請求之後,在本地找出你的公鑰,然後把它和你發送過來的公鑰進行比較。若兩密匙一致,服務器就用公匙加密“質詢”(challenge)並把它發送給客戶端軟件;
- 客戶端軟件收到“質詢”之後就可以用私鑰解密後再把它發送給服務器。
這種方式不需要在網絡上傳送口令,但你要記住密鑰的口令(在創建密鑰時會要求設置)。public key認證可以有效避免“中間人”攻擊。
創建密鑰:(公鑰加密算法有rsa和dsa兩種可選)
lfly@linux-oj9e:~/.ssh> ssh-keygen -t rsa (這裏指定rsa公鑰加密算法)
回車後ssh會詢問你密鑰要存放的位置,回車默認爲~/.ssh/id_rsa。然後又要求輸入密鑰的口令,回車默認爲空口令。成功創建則如下所示:
成功後可以看到.ssh文件夾下多了兩個文件:id_rsa 和id_rsa.pub
lfly@linux-oj9e:~/.ssh> ls
config id_rsa id_rsa.pub known_hosts known_hosts.old
上傳公鑰(id_rsa.pub)到遠程主機。有兩種方法:
方法1、用scp複製
確定遠程主機家目錄裏有沒有.ssh這個目錄,如果沒有則先遠程登陸並手動創建並設置權限爲755
$ mkdir .ssh
$ chmod 755 .ssh
然後回到本地用scp上傳文件到遠程家目錄下並重命名爲authorized_keys文件:
lfly@linux-oj9e:~/.ssh> scp id_rsa.pub [email protected]:~/.ssh/authorized_keys
輸入密碼後則可完成。之後遠程連接即可不用輸入密碼,如果不要求輸入密碼,說明還沒成功:此時要檢查遠程主機家目錄上.ssh目錄權限應該要爲700以及.ssh目錄下的authorized_keys文件權限應該要爲644。
方法2、用ssh-copy-id命令
lfly@linux-oj9e:~/.ssh> ssh-copy-id -i ~/.ssh/id_rsa.pub [email protected]
這裏是要複製到192.168.56.101的lfly的家目錄上,權限會自動設置,很方便。
方法1如果需要多臺主機無密碼訪問該遠程主機(即要多次添加不同的id_rsa.pub到authorized_keys文件)不可行,因爲每次用scp上傳會覆蓋原有的內容。 而用方法2則會自動在authorized_keys文件結尾添加而非覆蓋,所以更方便。
SSH做socks代理翻牆
需要用到的工具:
- Tsocks 代碼託管:https://github.com/pc/tsocks
- 一個能連接到外國ip主機的ssh帳號
Tsocks 是一個透明 SOCKS 代理軟件。Ubuntu源裏的這個包,opensuse用戶可以在www.opensuse.org裏搜索到這個包。
1. 安裝後要配置/etc/tsocks.conf文件(以下爲部分內容)
# We can access 192.168.0.* directly
local = 192.168.0.0/255.255.255.0 # Otherwise we use the server
server = 127.0.0.1
server_port = 7070
代理服務器爲127.0.0.1即本機,端口爲7070
2. 然後用ssh搭建ssh隧道:
lfly@linux-oj9e:~> ssh -fNC -D 7070 111.111.111.111
這裏注意:上面填寫的111.111.111.111替換成你能通過ssh登陸的外國主機的ip (關於ssh隧道詳見參考資料)
3. Tsocks配置好了以及ssh隧道搭建成功後娐可翻牆
Tsocks 的用法是在你要運行的工具前面加上 tsocks :
例如我要用火狐翻牆:
lfly@linux-oj9e:~> tsocks firefox
歡迎訪問本人網站:http://www.programfish.com
LinuxCoder社區: http://linuxcoder.org
注意:轉載請註明 “作者:廣州Linux愛好者+雲計算 刁金明”