目錄
- ssh
- ssh是什么
- ssh安裝
- 使用ssh登錄遠(yuǎn)程主機
- 退出登錄
- 使用ssh執(zhí)行單條指令
- 密鑰驗證
- 詳細(xì)操作
- scp
- rsync
- sftp
- 進(jìn)階
ssh
ssh是什么
ssh (Secure SHell)
簡單說,ssh是一種網(wǎng)絡(luò)協(xié)議,用于計算機之間的加密登錄。你可以通過 ssh 服務(wù)遠(yuǎn)程訪問其他安裝有 ssh 服務(wù)的主機,也可以向/從遠(yuǎn)程主機復(fù)制文件。ssh 服務(wù)包括 ssh,scp,sftp,rsync。
如果一個用戶從本地計算機,使用ssh協(xié)議登錄另一臺遠(yuǎn)程計算機,我們就可以認(rèn)為,這種登錄是安全的,即使被中途截獲,密碼也不會泄露。
以下實驗均以客戶端:MacOS Sierra 和服務(wù)端 :Ubuntu 為組合, 如果你沒有兩臺主機供實驗,遠(yuǎn)程主機的地址可以使用 localhost 替代
ssh安裝
大部分 linux 發(fā)行版都只默認(rèn)包含ssh 客戶端(即只能作為客戶端連接其他主機,而不能被其他主機遠(yuǎn)程訪問),要想讓你的 linux 供他人遠(yuǎn)程訪問,還必須安裝 ssh 服務(wù)器端軟件(openssh-server),Ubuntu 通過如下指令安裝:
apt-get install openssh-server
安裝完成后,我們的服務(wù)器主機就具備了被遠(yuǎn)程訪問的能力了
使用ssh登錄遠(yuǎn)程主機
在本地主機終端輸入ssh username@addr連接遠(yuǎn)程主機。其中 username 為遠(yuǎn)程主機中存在的用戶名,addr 為遠(yuǎn)程主機的 ip 地址。如ssh gustplus@192.168.1.10就是以gustplus 賬號登錄地址為192.168.1.10的主機。
如果是第一次登錄該主機,你會收到類似如下信息:
The authenticity of host '192.168.1.10 (192.168.1.10)' can't be established.
RSA key fingerprint is a4:28:03:85:89:6d:08:fa:99:15:ed:fb:b0:67:55:89.
Are you sure you want to continue connecting (yes/no)?yes
當(dāng)輸入 yes 后會顯示如下信息:
Warning: Permanently added '192.168.1.10' (RSA) to the list of known hosts.
此時,你已接收到了服務(wù)器端發(fā)給你的公鑰(public key),并存儲在你的~/.ssh/known_hosts文件中。這行為保證了你與服務(wù)器端的通信經(jīng)過了RSA加密。
此時, 客戶端主機的~/.ssh/known_hosts的內(nèi)容如下
192.168.1.10 ssh-rsa XXXXXX3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==
此時,客戶端主機已經(jīng)與遠(yuǎn)程主機建立的加密的安全連接,你可以像在本地終端一樣操作遠(yuǎn)程主機了
退出登錄
你可以通過 exit 指令來退出登錄
使用ssh執(zhí)行單條指令
你可以如下指令使用 ssh 執(zhí)行一條指令:
$ ssh gustplus@192.168.1.10 hostname
johndoe@10.140.67.23's password: **********
friday
比如上條指令在192.168.1.10上執(zhí)行了 hostname 指令
如果你需要執(zhí)行的指令包含選項或參數(shù),最好將整條指令用雙引號(“”)包裹
$ ssh gustplus@192.168.1.10 "cat myfile"
不然像"~/"這樣具有特殊含義的指示符會被提前展開,如下面這條例子:
shizhandeMacBook-Pro:~ shizhan$ ssh gustplus@192.168.1.10 ls ~/
ls: cannot access '/Users/shizhan/': No such file or directory
這里的~/被提前展開為 '/Users/shizhan/'而不是期望的‘/home/gustplus’。使用雙引號的效果如下:
shizhandeMacBook-Pro:~ shizhan$ ssh shizhan@192.168.1.10 "ls ~/"
Desktop
Documents
Downloads
examples.desktop
Music
Pictures
Public
shell.sh
sub_shell.sh
Templates
Videos
同時需要注意的是,如果你的指令中含有相對路徑,這條相對路徑是相對于用戶的home目錄而言的,比如上例中的'~/'指代的是 gustplus 的 home 目錄/home/gustplus
密鑰驗證
如果你頻繁的使用 ssh工具與遠(yuǎn)程主機交互,你就會發(fā)現(xiàn)每次都要輸入密碼是一件多么糟心的事,所以除了密碼驗證,ssh 還提供了密鑰驗證。下面是它的工作原理:
- 首先由你在本地主機上創(chuàng)建一對公鑰和私鑰
- 私鑰由本地主機自行保管,公鑰上傳到需要登錄的遠(yuǎn)程主機
- 在上傳的公鑰放置到合適位置之后,之后的 ssh 連接會直接將遠(yuǎn)程主機的公鑰與本地主機的私鑰進(jìn)行匹配,而無需在輸入密碼
詳細(xì)操作
本地主機通過
ssh-keygen -t rsa -P ''生成公私鑰對。
其中-P表示密碼,-P '' 就表示空密碼,也可以不用-P參數(shù),這樣就要三車回車,用-P就一次回車。
-t表示密鑰的加密類型,可以選擇的加密類型有:dsa, ecdsa, ed25519, rsa, rsa1
指令會在/home/$(user_name)目錄下生成.ssh/目錄,并在.ssh目錄下生成id_rsa和id_rsa.pub兩份公鑰和私鑰文件執(zhí)行 ssh-copy-id,將生成的公鑰文件上傳至遠(yuǎn)程主機
$ ssh-copy-id -i ~/.ssh/id_rsa.pub gustplus@192.168.1.10
其中 ssh-copy-id的說明如下:
ssh-copy-id [-f] [-n] [-i [公鑰文件路徑]] [-p 端口號] [-o ssh 選項] [user@]hostname
此操作會將本地主機的公鑰的內(nèi)容添加到遠(yuǎn)程主機指定用戶home 路徑下的.ssh/authorized_keys文件中
當(dāng)然這些操作也可以通過手動完成
scp ~/.ssh/id_rsa.pub gustplus@192.168.1.10:./ #將 id_rsa.pub 文件拷貝到遠(yuǎn)程主機的 home 目錄下
ssh gustplus@192.168.1.10 "touch ~/.ssh/authorized_keys;\
cat ~/id_rsa.pub >> ~/.ssh/authorized_keys;\
chmod 644 ~/.ssh/authorized_keys" #將 id_rsa.pub 的內(nèi)容添加到~/.ssh/authorized_keys文件中,并修改該文件的權(quán)限,別忘了雙引號噢!
- 接下來在通過 ssh 登錄遠(yuǎn)程主機試試,是不是不需要密碼了?當(dāng)然使用到 ssh 服務(wù)的所有操作(ssh, scp, rsync...)都將不需要輸入密碼了!
scp
在客戶端和服務(wù)器之間傳輸文件
scp 的傳輸也是經(jīng)過加密的
scp from to
from和to 分別為服務(wù)器或客戶端路徑路徑中的一個,其中服務(wù)器的路徑格式為user_name@$ip_addr: $path。如下面的例子,是將本地/Users/shizhan/memo的文件拷貝到服務(wù)器的/tmp路徑下
$ scp /Users/shizhan/memo gustplus@192.168.1.10:/tmp
shizhan@192.168.1.10's
memo 100%|****************| 153 0:00
和cp指令一樣,你可以使用-r 選項拷貝一整個目錄
$ scp -r /etc/ shizhan@192.168.1.10:etc/
afpovertcp.cfg 100% 515 153.1KB/s 00:00
afpovertcp.cfg~orig 100% 515 96.5KB/s 00:00
aliases 100% 9970 1.3MB/s 00:00
......
你可能會想到,可以利用scp來進(jìn)行數(shù)據(jù)的備份,但不幸的是,scp本身有些屬性注定了它并不適合備份:
- 屬性丟失。權(quán)限或者時間屬性和 原始文件不一樣。這是備份所不希望看到的
下面是使用scp 拷貝文件后的對比:
#原始文件
-rw-rw-rw- 1 shizhan staff 398 5 31 2015 id_rsa.pub
#復(fù)制
scp ~/Documents/id_rsa.pub gustplus@192.168.1.10:./
#復(fù)制后的文件
ssh gustplus@192.168.1.10 "ls -al id_rsa.pub"
-rw-rw-r-- 1 shizhan shizhan 398 8月 5 11:59 id_rsa.pub
可見,復(fù)制后,文件的權(quán)限(權(quán)限會由遠(yuǎn)程用戶的umask 限制)和日期屬性都發(fā)生了改變
軟鏈接丟失。如果拷貝過程中遇到軟鏈接,
scp將會拷貝鏈接指向的文件/目錄而不是鏈接本身拷貝了重復(fù)的文件。如果執(zhí)行兩次相同的拷貝操作且被拷貝的文件沒有改動,拷貝行為仍會執(zhí)行,浪費
那么,有沒有適合備份的指令吶?當(dāng)然有!
rsync
使用rsync就可以避免scp在備份文件時的這些問題
通過-avl 選項(-a (recursive archive), -v (verbose), and -l (copy symbolic links))可以實現(xiàn)文件的備份而沒有以上的問題(但文件的 user:group 還是會變成登錄用戶的 user:group)
當(dāng)重復(fù)備份相同的文件時,rsync命令會忽略沒有修改的文件
#第一次備份
shizhandeMacBook-Pro:~ shizhan$ rsync -avl rsync_test gustplus@192.168.1.10:
building file list ... done
rsync_test/
rsync_test/test.txt
sent 151 bytes received 48 bytes 79.60 bytes/sec
total size is 0 speedup is 0.00
#第二次備份
shizhandeMacBook-Pro:~ shizhan$ rsync -avl rsync_test gustplus@192.168.1.10:
building file list ... done
sent 103 bytes received 20 bytes 35.14 bytes/sec
total size is 0 speedup is 0.00
我們可以發(fā)現(xiàn),第二次備份并沒有復(fù)制文件,正是因為rsync忽略了沒有修改的文件
使用-avl 選項是備份的好方法,但如果想要兩臺機器上的兩個目錄完全相同,還需要其他操作,看下面的例子:
#創(chuàng)建測試文件夾及文件
$ mkdir scp_test
$ touch scp_test/scp_test.txt
#備份文件夾到遠(yuǎn)程主機
$ rsync -avl scp_test gustplus@192.168.1.10:
#刪除本地文件
$ rm scp_test/*
#再次備份文件夾到遠(yuǎn)程主機
$ rsync -avl scp_test gustplus@192.168.1.10:
這時候我們查看遠(yuǎn)程主機里的scp_test文件夾,會發(fā)現(xiàn)本地已刪除的文件仍然存在
$ ll scp_test/
total 8
drwxr-xr-x 2 gustplus gustplus 4096 8月 5 15:58 ./
drwxr-xr-x 18 gustplus gustplus 4096 8月 5 15:57 ../
-rw-r--r-- 1 gustplus gustplus 0 8月 5 15:55 scp_test.txt
如果你想備份所有的歷史文件以防止被備份主機上文件被誤刪除,這種結(jié)果是正確的。但如果只是想備份現(xiàn)有數(shù)據(jù),這可以添加--delete選項來消除這種行為
$ rsync -avl --delete scp_test shizhan@192.168.1.10:
building file list ... done
deleting scp_test/scp_test.txt
scp_test/
sent 91 bytes received 26 bytes 33.43 bytes/sec
total size is 0 speedup is 0.00
添加--delete選項后,我們可以看到本機刪除的文件在備份主機上的相應(yīng)文件也刪除了
sftp
如果你并不知道遠(yuǎn)程主機的目錄結(jié)構(gòu),可以使用 sftp來創(chuàng)建通過 ssh 服務(wù)的 ftp 對話(session)。通過 sftp,你可以在ssh連接到遠(yuǎn)程主機后切換目錄(cd),顯示目錄內(nèi)容(ls)以及從主機上下載文件。
不要被指令名字誤導(dǎo),其實sftp 和 ftp協(xié)議沒有任何關(guān)系,也沒有使用 ftp 服務(wù)器。
更多操作可在運行 sftp 后輸入 help查看
sftp> help
Available commands:
bye Quit sftp
cd path Change remote directory to 'path'
chgrp grp path Change group of file 'path' to 'grp'
chmod mode path Change permissions of file 'path' to 'mode'
chown own path Change owner of file 'path' to 'own'
df [-hi] [path] Display statistics for current directory or
filesystem containing 'path'
exit Quit sftp
get [-afPpRr] remote [local] Download file
reget [-fPpRr] remote [local] Resume download file
reput [-fPpRr] [local] remote Resume upload file
help Display this help text
lcd path Change local directory to 'path'
lls [ls-options [path]] Display local directory listing
lmkdir path Create local directory
ln [-s] oldpath newpath Link remote file (-s for symlink)
lpwd Print local working directory
ls [-1afhlnrSt] [path] Display remote directory listing
lumask umask Set local umask to 'umask'
mkdir path Create remote directory
progress Toggle display of progress meter
put [-afPpRr] local [remote] Upload file
pwd Display remote working directory
quit Quit sftp
rename oldpath newpath Rename remote file
rm path Delete remote file
rmdir path Remove remote directory
symlink oldpath newpath Symlink remote file
version Show SFTP version
!command Execute 'command' in local shell
! Escape to local shell
? Synonym for help
進(jìn)階
你可以編輯/etc/ssh/sshd_config來修改 ssh 服務(wù)的行為
/etc/ssh/sshd_config文件在行為定義的前面都有簡明的注釋,這里摘錄一些常用的選項:
# What ports, IPs and protocols we listen for
# ssh服務(wù)監(jiān)聽的端口
Port 22
# HostKeys for protocol version 2
# 用于加密的密鑰路徑, 還記得之前說的 “在第一次登錄遠(yuǎn)程主機時會接收到服務(wù)器端發(fā)給你的公鑰”?嗎,
# 如果你查看~/.ssh/known_hosts中對應(yīng)主機的記錄,會發(fā)現(xiàn)這條數(shù)據(jù)與下面指定的四個文件中的一個是一樣的(根據(jù)加密方法的不同來選擇文件)
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
HostKey /etc/ssh/ssh_host_ecdsa_key
HostKey /etc/ssh/ssh_host_ed25519_key
想讓你的遠(yuǎn)程主機更安全?當(dāng)然可以。
在你設(shè)置好所有允許遠(yuǎn)程登錄主機的免密碼登錄后,你可以通過修改/etc/ssh/sshd_config配置來禁止使用密碼登錄
PasswordAuthentication no
這樣沒有加入到信任列表的主機將不能登錄這臺主機,即使他有密碼也不行,這樣即使你不小心泄露了密碼,對方也無法入侵你的主機
通過添加一行
PermitRootLogin no
到/etc/ssh/sshd_config配置文件中, 任何嘗試通過root密碼登錄你的主機的連接都會被駁回
Permission denied
所有修改都會在重啟 ssh 服務(wù)后生效
service ssh restart