802.1X 賬號密碼+裝置資訊雙重認證
阿新 • • 發佈:2020-09-25
## 名詞解釋
### 802.1X:
IEEE802 LAN/WAN 委員會為解決無線區域網網路安全問題,提出了 802.1X 協議。後來,802.1X協議作為區域網埠的一個普通接入控制機制在乙太網中被廣泛應用,主要解決乙太網內認證和安全方面的問題。802.1X 協議是一種基於埠的網路接入控制協議(port based network access control protocol)。“基於埠的網路接入控制”是指在區域網接入裝置的埠這一級對所接入的使用者裝置進行認證和控制。連線在埠上的使用者裝置如果能通過認證,就可以訪問區域網中的資源;如果不能通過認證,則無法訪問區域網中的資源。
### EAP協議:
EAP(Extensible Autllentication Protocol) 協議是 802.1X協議定義的一種報文封裝格式,主要用於在客戶端和裝置端之間傳送EAP協議報文,以允許EAP協議報文在LAN上傳送。目前可以採用的EAP型別包括:EAP-MD5、LEAP、PEAP、EAP—TLS 等方式。本文主要使用的協議為EAP-MD5協議,進行802.1X網路認證。
### FreeRADIUS:
RADIUS認證伺服器(Remote Authentication Dial In User Service,遠端使用者撥號認證系統)是目前應用最廣泛的AAA協議(AAA=authentication、Authorization、Accounting,即認證、授權、計費),FreeRADIUS包含一個radius伺服器和radius-client,可以對支援radius協議的網路裝置進行鑑權記賬。
### RSA非對稱加密:
對稱加密演算法在加密和解密時使用的是同一個祕鑰,與對稱加密演算法不同,非對稱加密演算法需要兩個金鑰:[公開金鑰](publickey)和[私有金鑰](privatekey)。公開金鑰與私有金鑰是一對,如果用公開金鑰對資料進行加密,只有用對應的私有金鑰才能解密;如果用私有金鑰對資料進行加密,那麼只有用對應的公開金鑰才能解密。因為加密和解密使用的是兩個不同的金鑰,所以這種演算法叫作非對稱加密演算法。
## 問題&&現狀
目前802.1X網路認證中EAP-MD5協議主要流程就是客戶端傳送使用者賬號和經過MD5加密後的密碼到RADIUS認證伺服器,RADIUS服務通過呼叫 OpenLDAP/Mysql 等元件,查詢對應的使用者是否存在,並校驗密碼是否一致,來判斷使用者是否合法,然後迴應認證成功/失敗報文到接入裝置,接入裝置根據RADIUS伺服器響應的報文,向客戶端響應成功/失敗狀態,並設定埠授權狀態,從而控制使用者是否能通過埠訪問網路。
僅針對賬號密碼進行認證,這樣的驗證方式單一而且缺乏力度,忽略了終端安全。按照目前的認證方式,一旦使用者密碼不慎洩漏,非法使用者可以通過不可信的終端接入網內,從而存在很多安全隱患。在伺服器、網路、終端這樣三位一體的計算機通訊系統上,終端是最為龐大的主體,而且攻擊也多半是從終端發起的。終端將成為我們安全體系中越發不可忽視的一環。只要保證目前系統中的所有主體都是安全可信賴的,而新的主體在加入網路時也通過了安全性驗證,那麼無論網路規模如何發展,整個體系的安全性都能得到很好的保障。
## 技術方案
為了滿足網路准入安全性要去,本方案主要是在原有的EAP-MD5協議賬號密碼單一認證基礎上,再通過驗證終端裝置的硬體資訊(MAC地址,CPU序列號,硬碟序列號等),在進行802.1X網路認證的時,實現 賬號密碼+裝置資訊 雙重認證,從而提高對接入使用者與終端裝置的可信性和可控性管理。
### 整體設計
#### 802.1X賬號密碼+裝置資訊認證總體可以劃分為下面幾個模組
1. 裝置認證服務模組:進行裝置資訊的錄入,並進行裝置證書校驗等功能
2. 客戶端模組:客戶端模組主要是發起經過改造後的802.1X認證協議
3. freeradius認證服務模組:freeradius服務模組主要負責呼叫OpenLDAP/Mysql進行賬號密碼認證,並轉發EAP-MD5協議相關資訊到裝置認證服務端模組,從而完成裝置資訊的校驗
#### 改造前 EAP-MD5認證 流程如下
如圖所示:
![avatar](https://images.cnblogs.com/cnblogs_com/MR-YY/1817620/o_200730135851%E5%9B%BE1.png)
1. 當用戶有訪問網路需求時開啟 802.1X 客戶端程式,輸入已經申請、登記過的使用者名稱和碼,發起連線請求(EAPOL-Start 報文)。此時,客戶端程式將發出請求認證的報文給裝置端,開始啟動一次認證過程。
2. 裝置端收到請求認證的資料幀後,將發出一個請求幀(EAP-Request/Identity 報文)要求使用者的客戶端程式傳送輸入的使用者名稱。
3. 客戶端程式響應裝置端發出的請求,將使用者名稱資訊通過資料幀(EAP-Response/Identity 報文)傳送給裝置端。裝置端將客戶端傳送的資料幀經過封包處理後(RADIUS Access-Request 報文)送給認證伺服器進行處理。
4. RADIUS 伺服器收到裝置端轉發的使用者名稱資訊後,將該資訊與資料庫中的使用者名錶對比,找到該使用者名稱對應的密碼資訊,用隨機生成的一個加密字對它進行加密處理,同時也將此加密字通過 RADIUS Access-Challenge 報文傳送給裝置端,由裝置端轉發給客戶端程式。
5. 客戶端程式收到由裝置端傳來的加密字(EAP-Request/MD5 Challenge 報文)後,用該加密字對密碼部分進行加密處理(此種加密演算法通常是不可逆的),生成 EAP-Response/MD5 Challenge 報文,並通過裝置端傳給認證伺服器。
6. RADIUS 伺服器將收到的已加密的密碼資訊(RADIUS Access-Request 報文)和本地經過加密運算後的密碼資訊進行對比,如果相同,則認為該使用者為合法使用者,反饋認證通過的訊息(RADIUS Access-Accept 報文和 EAP-Success 報文)。
#### 改造後 賬號密碼+裝置資訊認證 流程如下
如圖所示:
![avatar](https://images.cnblogs.com/cnblogs_com/MR-YY/1817620/o_200730135907%E5%9B%BE2.png)
1. 在客戶端發起802.1X網路認證之前,裝置認證服務端需要主動採集終端裝置相關資訊(MAC地址,CPU序列號,硬碟序列號等),通過SHA256摘要演算法,生成裝置資訊摘要,將裝置相關資訊儲存到裝置認證服務端資料庫中
2. 通過改造原有802.1X 客戶端程式,在改造前流程第5步,傳送 MD5 Challenge 的同時,讀取出端裝置相關資訊並生成裝置資訊摘要,並通過RSA非對稱加密演算法,加密摘要資訊,通過EAP-MD5協議擴充套件欄位 EAP-MD5 Extra Data 傳遞到freeradius認證伺服器
3. freeradius認證伺服器通過配置開啟自身rlm_rest模組,將加密後的裝置摘要資訊轉發到裝置認證服務模組
4. 裝置認證服務模組讀取加密後的摘要資訊,通過私鑰進行解密,然後在認證服務端資料庫中進行查詢,如果可以匹配到同樣的摘要資訊,則表示該終端裝置資訊合法,返回成功狀態碼給freeradius認證伺服器,freeradius認證伺服器會結合賬號密碼認證結果統一判斷,如果 賬號密碼+裝置資訊 都認證通過,則允許使用者訪問網路,否則不允許使用者訪問網路
### 關鍵程式碼
#### 客戶端相關程式碼
```
func (h *Handle) SendResponseMD5Chall(id uint8, salt, user, pass []byte) error {
// MD5 Challenge MD5加密後的密碼資訊
plain := []byte{id}
plain = append(plain, pass...)
plain = append(plain, salt[:0x10]...)
cipher := md5.Sum(plain)
data := append([]byte{uint8(len(cipher))}, cipher[:]...)
//初始化金鑰對
rsaCryptoKey := GenRasKeyFromPem("./config/client_private.pem", "./config/server_public.pem")
//獲取裝置資訊摘要(64位字串)
deviceInfo := GetSHA256DeviceInfo()
//加密裝置資訊摘要
enc, err := rsaCryptoKey.RsaEncrypt([]byte(deviceInfo))
if err != nil {
return err
}
//base64編碼
base64ExtarData := base64.StdEncoding.EncodeToString(enc)
//將加密後的裝置資訊摘要加入到EAP請求包內
data = append(data, []byte(base64ExtarData)...)
eth := layers.Ethernet{
SrcMAC: h.srcMacAddr,
DstMAC: h.dstMacAddr,
EthernetType: layers.EthernetTypeEAPOL,
}
eapol := layers.EAPOL{
Version: 0x01,
Type: layers.EAPOLTypeEAP,
Length: uint16(5 + len(data)),
}
eap := layers.EAP{
Code: layers.EAPCodeResponse,
Id: id,
Type: layers.EAPTypeOTP,
TypeData: data,
Length: eapol.Length,
}
if err := h.send(ð, &eapol, &eap, &fillLayer); err != nil {
return err
}
return nil
}
```
#### 裝置認證服務模組
```
//授權操作
// http.StatusNoContent 對應freeradius ok 狀態
// http.StatusUnauthorized 對應freeradius reject 狀態
func Authorize(c *gin.Context) {
var (
err error = nil
data []byte = nil
auth model.AuthorizeInfo = model.AuthorizeInfo{}
)
//讀取freeradius rest模組轉發的訊息
data, err = ioutil.ReadAll(c.Request.Body)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
log.Info("Authorize data:%v", string(data))
err = json.Unmarshal(data, &auth)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
if len(auth.EAPMessage) <= 46 {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, "Authorize wrong length"))
return
}
//EAPMessage訊息結構:前14位為請求頭資訊,15-46中間32位是MD5加密後的密碼資訊,46-末尾是Extra Data 擴充套件欄位的資訊
extarData := auth.EAPMessage[46:]
log.Info("Authorize extarData:%v", extarData)
//解析裝置摘要資訊
decHexExtarData, err := hex.DecodeString(extarData)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
decBase64ExtarData, err := base64.StdEncoding.DecodeString(decHexExtarData)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
//解密裝置摘要資訊
deviceInfo, err := config.RsaCryptoKey.RsaDecrypt(decBase64ExtarData)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
//校驗裝置摘要資訊是否在資料庫內
_, err = dao.IsExist(deviceInfo)
if err != nil {
c.JSON(http.StatusUnauthorized, model.ErrResultModel(model.ParamErr, err.Error()))
return
}
//校驗裝置摘要資訊通過則響應 http.StatusNoContent 204 狀態
c.JSON(http.StatusNoContent, model.OkResultModel("success"))
return
}
```
#### freeradius認證服務模組
freeradius認證服務模組主要為相關配置,以實現認證訊息轉發的功能
#### 編譯安裝
rlm_rest 模組預設是不會安裝的,需要手動編譯安裝 freeradius 服務,編譯安裝freeradius-rest 模組時,需要進入 /src/modules/rlm_rest 模組執行 ./configure 檢查是否確少依賴包,安裝完對應的依賴包,否則會導致 freeradius 安裝成功,而 rlm_rest 模組編譯失敗的問題
#### 配置rest模組
1. 通過軟連線啟用rest模組
```
ln -s /usr/local/etc/raddb/mods-available/rest /usr/local/etc/raddb/mods-enabled/rest
```
2. 修改rest相關配置
```
vim /usr/local/etc/raddb/mods-enabled/rest
//裝置認證服務閘道器
connect_uri = "http://127.0.0.1:2017"
//設定轉發引數和具體URL
authorize {
uri = "${..connect_uri}/user/authorize"
method = 'post'
body = 'json'
data = '{"user_name":"%{User-Name}","eap_message":"%{EAP-Message}","mac_id":"%{Calling-Station-Id}"}'
tls = ${..tls}
}
```
3. 修改default檔案,認證流程新增rest模組
```
vim /usr/local/etc/raddb/sites-enabled/default
authorize{
rest
}
authenticate{
Auth-Type rest{
rest
}
}
accouting{
rest
}
```
4. 重啟 freeradius認證服務 即可實現認證請求的轉發
## 實驗驗證
環境搭建:需要一臺UOS客戶端兩臺(一臺裝置資訊已錄入,一臺裝置資訊未錄入,安裝經過改造後的802.1X協議的客戶端),一臺UOS服務端(編譯安裝freeradius),一臺支援802.1X協議交換機(設定埠開啟802.1X協議認證)
### 場景一:測試 賬號密碼正確+裝置資訊未登記 場景
如圖所示:
![avatar](https://images.cnblogs.com/cnblogs_com/MR-YY/1817620/o_200730135913%E5%9B%BE3.png)
客戶端2發起802.1X認證請求,賬號為:yangyi,密碼為:testing,裝置摘要資訊為:a4de2da2c87361550d24110dd18eb4c021e20db461102e677683aab5490e3484,在 EAP-MD5 請求 Response MD5-Challenge 節點,將經過加密後的摘要資訊傳送到裝置認證伺服器端,因為此裝置摘要資訊未在裝置認證伺服器端登記,所以交換機響應 Failure 狀態,使用者入網失敗
### 場景二:測試 賬號密碼正確+裝置資訊已登記 場景
如圖所示:
![avatar](https://images.cnblogs.com/cnblogs_com/MR-YY/1817620/o_200730135920%E5%9B%BE4.png)
客戶端1發起802.1X認證請求,賬號為:yangyi,密碼為:testing,裝置摘要資訊為:21e20db461102e677683aab5490e3484a4de2da2c87361550d24110dd18eb4c0,在EAP-MD5 請求 Response MD5-Challenge 節點,將經過加密後的摘要資訊傳送到裝置認證伺服器端,因為此裝置摘要資訊已在裝置認證伺服器端登記,所以交換機響應 Success 狀態,使用者入網成功
## 小結
以上介紹了802.1X基於埠訪問控制協議的相關技術,提出並實現基於賬號密碼+裝置資訊雙重認證的方案,以及對802.1X協議的擴充套件。整個系統是在Linux平臺上基於802.1X認證的開源客戶端工具和伺服器端軟體FreeRADIUS進行新功能開發和改進,並最終實現了使用者賬號密碼認證和裝置資訊雙重認證的功能。所實現的系統在使用者發起入網請求時,客戶端軟體會自動獲取終端裝置資訊,並生成裝置資訊摘要,和經過MD5加密後密碼,一起傳送到FreeRADIUS認證伺服器,使得FreeRADIUS伺服器在完成對使用者身份驗證的同時也可以完成對終端裝置資訊的可信認證。最後的測試結果顯示,該方案可以滿足可信網路連線的基本功能需求,將來可以實際應用於可信網路的接入控制。
但目前的該方案也存在以下一些不足之處:
* EAP—MD5協議目前只能支援有線網路接入認證,對於無限網路接入認證,還需要進一步的研究
* 裝置擴充套件資訊雖然通過RSA非對稱加密後的密文進行傳輸,但公鑰儲存在客戶端,可能存在洩漏的風險,可以考慮對公鑰進行密碼保護,或者需要管理員許可權才可以讀取到公鑰資訊,或者直接由服務端下發證書給客戶端的方案
## 參考資料
* [802.1x技術介紹](http://www.h3c.com/cn/d_200812/624138_30003_0.htm#_Toc227664913)
* [freeradius官方文件](https://wiki.freeradius.org/Home)
* [freeradius原始碼](https://github.com/FreeRADIUS/freeradius-server)
* [基於golang的802.1x客戶端命令列工具](https://github.com/tr3ee/rjso