SSH SCP 遠程密鑰登錄配置和服務器間的文件傳輸


目錄

  1. ssh
    1. ssh是什么
    2. ssh安裝
    3. 使用ssh登錄遠程主機
    4. 退出登錄
    5. 使用ssh執行單條指令
    6. 密鑰驗證
      • 詳細操作
  2. scp
  3. rsync
  4. sftp
  5. 進階

ssh

ssh是什么

ssh (Secure SHell)
簡單說,ssh是一種網絡協議,用於計算機之間的加密登錄。你可以通過 ssh 服務遠程訪問其他安裝有 ssh 服務的主機,也可以向/從遠程主機復制文件。ssh 服務包括 ssh,scp,sftp,rsync。
如果一個用戶從本地計算機,使用ssh協議登錄另一台遠程計算機,我們就可以認為,這種登錄是安全的,即使被中途截獲,密碼也不會泄露。

以下實驗均以客戶端:MacOS Sierra 和服務端 :Ubuntu 為組合, 如果你沒有兩台主機供實驗,遠程主機的地址可以使用 localhost 替代

ssh安裝

大部分 linux 發行版都只默認包含ssh 客戶端(即只能作為客戶端連接其他主機,而不能被其他主機遠程訪問),要想讓你的 linux 供他人遠程訪問,還必須安裝 ssh 服務器端軟件(openssh-server),Ubuntu 通過如下指令安裝:

apt-get install openssh-server

安裝完成后,我們的服務器主機就具備了被遠程訪問的能力了

使用ssh登錄遠程主機

一般來說為了安全性考慮,端口號等一些參數並不會使用默認值。這樣的話命令就變成這樣:

ssh 用戶名@IP地址 -p 端口號

 

在本地主機終端輸入ssh username@addr連接遠程主機。其中 username 為遠程主機中存在的用戶名,addr 為遠程主機的 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

當輸入 yes 后會顯示如下信息:

Warning: Permanently added '192.168.1.10' (RSA) to the list of known hosts.

此時,你已接收到了服務器端發給你的公鑰(public key),並存儲在你的~/.ssh/known_hosts文件中。這行為保證了你與服務器端的通信經過了RSA加密。

此時, 客戶端主機的~/.ssh/known_hosts的內容如下

192.168.1.10 ssh-rsa XXXXXX3NzaC1yc2EAAAABIwAAAQEAq2A7hRGmdnm9tUDbO9IDSwBK6TbQa+PXYPCPy6rbTrTtw7PHkccKrpp0yVhp5HdEIcKr6pLlVDBfOLX9QUsyCOV0wzfjIJNlGEYsdlLJizHhbn2mUjvSAHQqZETYP81eFzLQNnPHt4EVVUh7VfDESU84KezmD5QlWpXLmvU31/yMf+Se8xhHTvKSCZIFImWwoG6mbUoWf9nzpIoaSjB+weqqUUmpaaasXVal72J+UX2B+2RPW3RcT0eOzQgqlJL3RKrTJvdsjE3JEAvGq3lGHSZXy28G3skua2SmVi/w4yCE6gbODqnTWlg7+wC604ydGXA8VJiS5ap43JXiUFFAaQ==

 

此時,客戶端主機已經與遠程主機建立的加密的安全連接,你可以像在本地終端一樣操作遠程主機了

退出登錄

你可以通過 exit 指令來退出登錄

使用ssh執行單條指令

你可以如下指令使用 ssh 執行一條指令:

$ ssh  gustplus@192.168.1.10 hostname
johndoe@10.140.67.23's password: **********
 friday

比如上條指令在192.168.1.10上執行了 hostname 指令
如果你需要執行的指令包含選項或參數,最好將整條指令用雙引號(“”)包裹

$ 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工具與遠程主機交互,你就會發現每次都要輸入密碼是一件多么糟心的事,所以除了密碼驗證,ssh 還提供了密鑰驗證。下面是它的工作原理:

  1. 首先由你在本地主機上創建一對公鑰和私鑰
  2. 私鑰由本地主機自行保管,公鑰上傳到需要登錄的遠程主機
  3. 在上傳的公鑰放置到合適位置之后,之后的 ssh 連接會直接將遠程主機的公鑰與本地主機的私鑰進行匹配,而無需在輸入密碼

詳細操作

  1. 本地主機通過ssh-keygen -t rsa -P ''生成公私鑰對。
    其中-P表示密碼,-P '' 就表示空密碼,也可以不用-P參數,這樣就要三車回車,用-P就一次回車。
    -t表示密鑰的加密類型,可以選擇的加密類型有:dsa, ecdsa, ed25519, rsa, rsa1
    指令會在/home/$(user_name)目錄下生成.ssh/目錄,並在.ssh目錄下生成id_rsa和id_rsa.pub兩份公鑰和私鑰文件

  2. 執行 ssh-copy-id,將生成的公鑰文件上傳至遠程主機

$ 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

此操作會將本地主機的公鑰的內容添加到遠程主機指定用戶home 路徑下的.ssh/authorized_keys文件中

當然這些操作也可以通過手動完成

scp ~/.ssh/id_rsa.pub gustplus@192.168.1.10:./  #將 id_rsa.pub 文件拷貝到遠程主機的 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 的內容添加到~/.ssh/authorized_keys文件中,並修改該文件的權限,別忘了雙引號噢!
  1. 接下來在通過 ssh 登錄遠程主機試試,是不是不需要密碼了?當然使用到 ssh 服務的所有操作(ssh, scp, rsync...)都將不需要輸入密碼了!

scp

在客戶端和服務器之間傳輸文件
scp 的傳輸也是經過加密的

scp from to

from和to 分別為服務器或客戶端路徑路徑中的一個,其中服務器的路徑格式為user_name@$ip_addr: $path。如下面的例子,是將本地/Users/shizhan/memo的文件拷貝到服務器的/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來進行數據的備份,但不幸的是,scp本身有些屬性注定了它並不適合備份:
  1. 屬性丟失。權限或者時間屬性和 原始文件不一樣。這是備份所不希望看到的
    下面是使用scp 拷貝文件后的對比:
#原始文件
-rw-rw-rw-   1 shizhan  staff     398  5 31  2015 id_rsa.pub
#復制
scp ~/Documents/id_rsa.pub gustplus@192.168.1.10:./
#復制后的文件
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 

可見,復制后,文件的權限(權限會由遠程用戶的umask 限制)和日期屬性都發生了改變

  1. 軟鏈接丟失。如果拷貝過程中遇到軟鏈接,scp將會拷貝鏈接指向的文件/目錄而不是鏈接本身

  2. 拷貝了重復的文件。如果執行兩次相同的拷貝操作且被拷貝的文件沒有改動,拷貝行為仍會執行,浪費

那么,有沒有適合備份的指令吶?當然有!

rsync

使用rsync就可以避免scp在備份文件時的這些問題

通過-avl 選項(-a (recursive archive), -v (verbose), and -l (copy symbolic links))可以實現文件的備份而沒有以上的問題(但文件的 user:group 還是會變成登錄用戶的 user:group)

當重復備份相同的文件時,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

我們可以發現,第二次備份並沒有復制文件,正是因為rsync忽略了沒有修改的文件

使用-avl 選項是備份的好方法,但如果想要兩台機器上的兩個目錄完全相同,還需要其他操作,看下面的例子:

#創建測試文件夾及文件
$ mkdir scp_test
$ touch scp_test/scp_test.txt
#備份文件夾到遠程主機
$ rsync -avl scp_test gustplus@192.168.1.10:
#刪除本地文件
$ rm scp_test/*
#再次備份文件夾到遠程主機
$ rsync -avl scp_test gustplus@192.168.1.10:

 

這時候我們查看遠程主機里的scp_test文件夾,會發現本地已刪除的文件仍然存在

$ 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

 

如果你想備份所有的歷史文件以防止被備份主機上文件被誤刪除,這種結果是正確的。但如果只是想備份現有數據,這可以添加--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選項后,我們可以看到本機刪除的文件在備份主機上的相應文件也刪除了

sftp

如果你並不知道遠程主機的目錄結構,可以使用 sftp來創建通過 ssh 服務的 ftp 對話(session)。通過 sftp,你可以在ssh連接到遠程主機后切換目錄(cd),顯示目錄內容(ls)以及從主機上下載文件。
不要被指令名字誤導,其實sftp 和 ftp協議沒有任何關系,也沒有使用 ftp 服務器。
更多操作可在運行 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

進階

你可以編輯/etc/ssh/sshd_config來修改 ssh 服務的行為
/etc/ssh/sshd_config文件在行為定義的前面都有簡明的注釋,這里摘錄一些常用的選項:

 # What ports, IPs and protocols we listen for 
 # ssh服務監聽的端口
Port 22

# HostKeys for protocol version 2
# 用於加密的密鑰路徑, 還記得之前說的 “在第一次登錄遠程主機時會接收到服務器端發給你的公鑰”?嗎,
# 如果你查看~/.ssh/known_hosts中對應主機的記錄,會發現這條數據與下面指定的四個文件中的一個是一樣的(根據加密方法的不同來選擇文件)
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

想讓你的遠程主機更安全?當然可以。

在你設置好所有允許遠程登錄主機的免密碼登錄后,你可以通過修改/etc/ssh/sshd_config配置來禁止使用密碼登錄

PasswordAuthentication no

這樣沒有加入到信任列表的主機將不能登錄這台主機,即使他有密碼也不行,這樣即使你不小心泄露了密碼,對方也無法入侵你的主機

通過添加一行

PermitRootLogin no

/etc/ssh/sshd_config配置文件中, 任何嘗試通過root密碼登錄你的主機的連接都會被駁回

 Permission denied

所有修改都會在重啟 ssh 服務后生效

service ssh restart

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM