目標
- 了解SSH是什么
- 服務端安裝SSH
- 客戶端安裝SSH
- ssh連接遠程服務
- ssh config配置講解(多服務器管理方式)
- ssh免密碼登入
- 權限問題
- 運維小技巧
SSH是什么
SSH的全稱為Secure Shell,即安全外殼協議。SSH是傳輸層和應用層上的安全協議,專門為遠程登錄會話和其他網絡服務提供安全性的協議。我們實際用到就是登入遠程服務器,或者從git遠程倉庫拉取代碼。
ssh認證過程分析
ssh涉及到兩個驗證:主機驗證和用戶身份驗證。通過主機驗證,再通過該主機上的用戶驗證,就能唯一確定該用戶的身份。一個主機上可以有很多用戶,所以每臺主機的驗證只需一次,但主機上每個用戶都需要單獨進行用戶驗證。
服務器安裝SSH
一般情況下,服務器上都已經安裝了ssh服務。可以通過 rpm -qa | grep ssh
來進行ssh服務的查看。
如果服務器上沒有安裝,那么我們可以直接通過yum install openssh-server
來進行安裝。
客戶端安裝SSH
一般情況下,Linux服務器都會安裝ssh客戶端(它其實是openssh的客戶端),但是如果安裝的是minial版本的Linux,那么就不會自帶ssh客戶端。
此時需要手動進行安裝,通過 yum install openssh-clients
啟動SSH服務
啟動:service sshd start,本質上是啟動/etc/init.d/sshd 服務。
開機運行:chkconfig sshd on
sshd服務是open ssh的一個后臺進程。
遠程連接SSH
ssh 賬號@ip -p 端口
ssh config配置文件的使用(多服務器管理方式)
上面我們已經學習了ssh命令的基本使用,使用ssh命令登入服務器,只需使用如下的方式即可。
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">ssh -p 26822 root@104.194.71.231</pre>
但是當我們管理多臺服務器時,如果每次登入我們都需要把ip和端口找出來來進行登入,會使得我們的運維非常麻煩。因此我們可以使用ssh config文件,將這些信息進行記錄,然后使用別名
的方式就可以完成登入。
SSH連接建立之前,會在系統中尋找它的配置文件,一般有兩個位置:
- /etc/ssh/ssh_config:這里是對所有的用戶適用的全局配置。
- ~/.ssh/config:這是個人用戶的配置,只對當前用戶生效,并且它會覆蓋全局配置。
注意:一般來說,~/.ssh 目錄的權限為700,config文件的權限需要為600。
- 在~/.ssh目錄下創建一個的config文件
- 輸入如下內容
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">host "linux1" HostName 104.194.71.231 User root Port 26822</pre>
它的格式是param value,或者是param=value,其中param對大小寫不敏感。
- 連接遠程服務器
通過這種方式,就可以簡化我們的命令使用方式,避免每次都需要輸入ip、賬號、端口等信息。可以在config中配置多個遠程服務器的信息。
config文件的權限問題
需要特別注意的是,如果當我們使用非root賬號時,可能會出現如下的錯誤信息:
其原因時config的文件的權限必須時600。
ssh 免密碼登入
ssh key 使用非對稱加密方式來生成公鑰和私鑰,其分別對應兩個文件,一般使用RSA算法。
私鑰存放在本地的~/.ssh目錄下。
公鑰可以對外公開,放在外部服務器的~/.ssh/authorized_keys
- 我們在客戶端使用ssh-keygen -t rsa 來生成公私鑰
在服務器端創建****authorized_keys****文件,將客戶端的公鑰信息拷貝到服務器端的authorized_keys文件中。如果authorized_keys已經有內容,則追加到尾部。
在客戶端,將私鑰進行加載。
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">ssh-add linux1_rsa</pre>
這個步驟貌似是可選的,并不一定要執行。
- 此時,我們就完成了免密碼登入到服務器。
ssh-copy-id命令使用
上面我們已經介紹了免密碼登入的方式,其本質就是將自己生成的公鑰,放到遠程服務器的authorized_keys文件中。正常情況下,我們需要登入到遠程服務器,然后創建authorized_keys文件,然后將公鑰信息復制到文件中,這樣雖然可以,但是處理起來有點麻煩。因此,我們可以使用更簡單的方式,ssh-copy-id命令來完成這個工作:
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">ssh-copy-id -i 公鑰文件 用戶@地址 -p 22</pre>
在config中配置私鑰文件
前面我們已經講了使用config管理多臺服務器以及使用公私鑰實現免密碼登入。現在我們將兩者進行結合。即在config配置文件中配置一個私鑰文件:
通過使用IdentifyFile來指定私鑰文件。
這樣我們就可以使用ssh hadoop102
就能直接登入遠程服務器了。
免密碼登入時出現的權限問題
對于.ssh目錄以及authorized_keys文件,必須按照特定的權限來設置,不能隨意設置。sshd為了安全,對屬主的目錄和文件權限有所要求。如果權限不對,則ssh的免密碼登陸不生效。
用戶目錄權限為 755 或者 700,就是不能是77x。
.ssh目錄權限一般為755或者700。
rsa_id.pub 及authorized_keys權限一般為644
rsa_id權限必須為600
ssh免密碼登陸設置時Authentication refused: bad ownership or modes錯誤解決方法
SSH拉取git代碼
在之前,我拉取代碼一直使用的是https的方式,每次都需要輸入賬號和密碼,特別的Low。對于這個問題,由于沒有阻塞日常的開發,所以我也不以為然。但是當你的同事給你的git地址是這樣的呢?git@git.coding.net:wzw/leave-a-message.git
臥槽,尷尬了,此時你用原來的方式似乎不行,最傻的方式就是你把它再次轉成https,這他么太Low了。。。。所以我對次做了一番研究,同時也看了幾篇文章進行了學習。
下面是我的一個研究過程,為了測試遠程倉庫,我特意注冊了coding.net這個賬號來進行測試。
最簡單的方式
- 生成公私鑰:
ssh-keygen -t rsa -C 784580872@qq.com
此時會生成id_rsa和id_ras.pub文件,然后你將你的公鑰貼到遠程服務器上去即可。
- 然后通過
ssh -T git@git.coding.net
來進行驗證是否ok,注意,這里使用的是ssh來驗證。
好了,就是如此簡單。但是這樣做有一個前提是,你的.ssh目錄下面必須有一個id_rsa文件,它里面存放了我的私鑰文件。
如果我將id_rsa文件刪除,將其改名為coding-net_id_rsa呢?是否可以?
再次執行,你會發現,它報權限被拒絕,臥槽。。。。為啥會這樣?此時我們可以開啟調式模式,看看上面的命令到底在干啥。
通過輸出信息我們可以看到,它會依次查找id_rsa、id_dsa等文件來獲取私鑰信息,由于我們的私鑰文件被重命名了,因此找不到,所以報了權限錯誤。
修改私鑰文件
通過上面的分析,我們知道如果要執行ssh -T git@git.coding.net 成功的話,必須有一個id_rsa文件。但是這會有一個問題,如果我有多個賬號,咋辦?兩個賬號不可能共用同一個私鑰文件,因為私鑰文件中包含了你的賬號信息。
為了解決這個問題,我們可以將私鑰的信息加載到ssh-agent的session中,那么當程序尋找私鑰的時候,會優先到ssh-agent的session中去尋找。這個session的生命周期很短,如果失效,就需要重新加載私鑰文件到新的session中。
加載私鑰文件到ssh-agent的session中,結果缺報了這個錯誤,原因是ssh-agent沒有開啟。
下面我們來開啟ssh-agent,然后進行私鑰文件的加載,最后連上遠程服務器。
通過上面的分析可以看到,如果當我們的私鑰文件不是id_rsa時,那么我們就需要將私鑰文件通過ssh-agent來進行加載到會話中才能實現免密碼的操作。
運維小技巧
ssh 端口修改
ssh服務默認開放的端口是22,它的配置文件是/``**etc/ssh/sshd_config**``**(sshd_config是服務器端文件,ssh_config是客戶端文件)**
** 。**我們可以通過修改該配置文件來改變ssh服務的端口。
注意,這里的Port可以配置多個,那么ssh服務在啟動的時候,就會綁定多個端口。
限制登錄的來源IP
限制登錄的來源IP有多種方式:
- 通過防火墻來進行配置
- 通過修改
/etc/hosts.allow
來進行限制。
基于防火墻的配置方式
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">Iptables -A INPUT -s 192.168.1.0/24 -p tcp -m state --state NEW -m - tcp --dport 2222 -j ACCEPT</pre>
基于/etc/hosts.allow的方式限制
<pre class="cm-s-default" style="color: rgb(89, 89, 89); margin: 0px; padding: 0px; background: none 0% 0% / auto repeat scroll padding-box border-box rgba(0, 0, 0, 0);">vim /etc/hosts.allow sshd:192.168.125.115:allow sshd:all:deny</pre>
這里我們配置了只有115這臺機器才可以訪問,其他IP不允許訪問該機器。當使用其他IP的機器進行訪問時,遠程服務器會自動關閉連接。(這里我使用了192.168.125.101來訪問)
僅允許特定用戶
一般情況下,我們都會配置禁止root賬戶遠程登入。我們可以通過修改/etc/ssh/sshd_config
文件來進行設置。
當我們配置了PermitRootLogin no
之后,就可以實現root賬號的禁止登入。
取消密碼驗證,只用密鑰對驗證
我們只需要將PasswordAuthentication
修改成no即可。當再次嘗試使用密碼登入時,就會報如下的錯誤:
只允許通過指定的網絡接口來訪問 SSH 服務
默認情況下,ssh服務啟動綁定的IP是0.0.0.0
。我們可以對其進行修改:
當修改完成之后,再次重啟SSH服務,它就會綁定我們給定的IP地址:
SSH端口轉發
ssh除了建立遠程的安全隧道外,還可以實現端口轉發的功能。我們看一個實際的業務場景:
MySQL服務器由于沒有公網IP,如果我們想要去訪問,只能通過跳板機來進行請求的轉發。這種轉發模式被稱為正向轉發
。其原理就是通過ssh來啟動一個端口,比如上面的7777,然后我們連接到7777;ssh又會建立一個與MySQL的連接,然后將我們的請求轉發到MySQL。這樣,我們就可以遠程登入到MySQL服務器了。
由于我們沒有公網IP,那么我就使用hadoop102來模擬跳板機,然后使用hadoop103來模擬MySQL服務。首先,我們會在Hadoop103上面啟動一個3306的端口。
然后我們在Hadoop102啟動7777端口,來讓其進行端口的轉發:
0.0.0.0:7777是讓hadoop102啟動7777端口,而hadoop103:6666是讓其將請求轉發到hadoop103的6666端口,而后面的root@hadoop103表示的是跳轉機地址,跳轉機的地址可以和目標機器不是同一臺,那么會多一次轉發。比如像下面這樣:
-N 告訴SSH客戶端,這個連接不需要執行任何命令,僅僅做端口轉發。
-f 告訴SSH客戶端在后臺運行。
下面我們通過連接Hadoop102的7777端口來進行測試:
通過這個例子,我們就完成了SSH端口正向轉發的實現,不過這樣做會存在安全隱患,相當于是把MySQL服務直接給開放出去了,因此我們還需要再防火墻這一層做IP白名單的限制。