基于free5gc+UERANSIM的5G注冊管理流程及安全服務分析
一、前言
隨著5G的快速建設,5G的安全問題受到越來越多的關注。本文首先借助free5gc和UERANSIM這兩個5G開源項目分析了《3GPP TS 23.502》標準中定義的用戶注冊管理流程,并對《3GPP TS 33.501》5G系統安全結構和流程標準中定義的安全服務進行了流量、代碼分析,以幫助安全研究人員增進對5G核心網安全,從而進行安全分析與測試。
本系列分為上下兩個部分,上半部分主要介紹《3GPP TS 23.502》中定義的5G用戶注冊管理的概念,并結合模擬環境對用戶注冊管理進行分析。下半部分則基于模擬環境對《3GPP TS 33.501》中定義的相關安全服務進行詳細分析。
本篇為該系列上半部分。
二、用戶注冊管理介紹
用戶注冊管理是用于 UE / 用戶和網絡之間進行注冊和注銷,在網絡建立上下文的過程,一個 UE / 用戶想要獲取網絡提供的業務必須先向網絡進行注冊。
注冊類型包含以下四種:
初次注冊(initial registration)
位置變更引起的網絡重新注冊(Mobility Registration Update)
周期性注冊(Periodic Registration Update)
緊急業務引發的注冊(Emergency Registration)
注冊管理涉及到的應用場景如下:
UE初次注冊網絡
UE周期性注冊網絡
UE位置變更引起的網絡重新注冊
緊急業務引發的網絡注冊
三、模擬環境介紹
本節簡單介紹了UERANSIM+free5gc環境,用戶可以通過使用arp、ifconfig、docker inspect及網橋brctl 相關命令,來收集容器IP及Mac地址相關信息,繪制的組網示意圖如下:
如上圖所示:環境基于ubuntu 20.04 VMware虛機部署,5gc網元分別部署在虛機的docker容器中。5gc各模擬網元與模擬RAN 通過虛擬網橋進行數據交換。物理機上的VMware 虛擬網卡作為DN(互聯網節點)通過虛擬網橋與容器中的UPF對接。詳細的搭建方法可以參考沉烽網絡安全實驗室的文章《free5gc+UERANSIM模擬5G網絡環境搭建及基本使用》 。
四、5G注冊管理流程分析
參考3GPP TS 23.502 V16.7.0,其協議的流程如下圖所示。
下文將基于UERANSIM+free5gc 模擬環境的報文、項目代碼、協議標準三位一體的對該注冊管理流程進行分析。
4.1 UE發送注冊請求
UE發送注冊請求(Registration Request)給RAN側,請求消息中包含了用戶的標識(SUPI或SUCI或GUTI),還包含了本次注冊的注冊類型,UE的能力等。
協議流程的位置:
對應流程圖中step1
4.2 AMF選擇
RAN側收到注冊請求后開始做AMF的選擇(AMF Selection),RAN將根據GUTI或者RAT+NSSAI選擇一個AMF,如果選擇不到,就選擇默認的AMF。
協議流程的位置:
對應流程圖中step2
4.3 RAN側向New AMF發送注冊請求
RAN向New AMF發送注冊請求Registration Request(這里是根據GUTI來選擇AMF的)。
協議流程的位置:
對應流程圖中step3
報文捕獲:
4.4 New AMF會向Old AMF獲取UE的上下文信息
由于核心網是不認識GUTI的,所以New AMF會向Old AMF獲取UE的上下文信息(SUPI號碼)。
協議流程的位置:
對應流程圖中step4,step5
代碼實現:
定位到free5gc amf項目/amf/ngap/handler.go中的HandleInitialUEMessage函數。
func HandleInitialUEMessage(ran *context.AmfRan, message *ngapType.NGAPPDU) {amfSelf := context.AMF_Self()
var rANUENGAPID *ngapType.RANUENGAPIDvar nASPDU *ngapType.NASPDUvar userLocationInformation *ngapType.UserLocationInformationvar rRCEstablishmentCause *ngapType.RRCEstablishmentCausevar fiveGSTMSI *ngapType.FiveGSTMSI// var aMFSetID *ngapType.AMFSetIDvar uEContextRequest *ngapType.UEContextRequest// var allowedNSSAI *ngapType.AllowedNSSAI
var iesCriticalityDiagnostics ngapType.CriticalityDiagnosticsIEList
請求IE包括:
id-RAN- UE-NGAP-ID
id-NAS-PDU
id-UserLocationInformation
id-RRCEStablishmentCause
id-UEContextRequest
接著由于UERANSIM+free5gc模擬環境屬于未部署UDSF場景,New AMF會向Old AMF獲取UE的上下文信息,代碼實現如下:
if ranUe == nil {var err errorranUe, err = ran.NewRanUe(rANUENGAPID.Value)if err != nil {ran.Log.Errorf("NewRanUe Error: %+v", err)}ran.Log.Debugf("New RanUe [RanUeNgapID: %d]", ranUe.RanUeNgapId)
if fiveGSTMSI != nil {ranUe.Log.Debug("Receive 5G-S-TMSI")
servedGuami := amfSelf.ServedGuamiList[0]
// <5G-S-TMSI> := <AMF Set ID><AMF Pointer><5G-TMSI>// GUAMI := <MCC><MNC><AMF Region ID><AMF Set ID><AMF Pointer>// 5G-GUTI := <GUAMI><5G-TMSI>tmpReginID, _, _ := ngapConvert.AmfIdToNgap(servedGuami.AmfId)amfID := ngapConvert.AmfIdToModels(tmpReginID, fiveGSTMSI.AMFSetID.Value, fiveGSTMSI.AMFPointer.Value)
tmsi := hex.EncodeToString(fiveGSTMSI.FiveGTMSI.Value)
guti := servedGuami.PlmnId.Mcc + servedGuami.PlmnId.Mnc + amfID + tmsi
// 如果自上次注冊請求過程以來服務AMF已更改,則調用Namf_Communication_UEContextTransfer// Described in TS 23.502 4.2.2.2.2 step 4 (without UDSF deployment)if amfUe, ok := amfSelf.AmfUeFindByGuti(guti); !ok {ranUe.Log.Warnf("Unknown UE [GUTI: %s]", guti)} else {ranUe.Log.Tracef("find AmfUe [GUTI: %s]", guti)
if amfUe.CmConnect(ran.AnType) {ranUe.Log.Debug("Implicit Deregistration")ranUe.Log.Tracef("RanUeNgapID[%d]", amfUe.RanUe[ran.AnType].RanUeNgapId)amfUe.DetachRanUe(ran.AnType)}// TODO: stop Implicit Deregistration timerranUe.Log.Debugf("AmfUe Attach RanUe [RanUeNgapID: %d]", ranUe.RanUeNgapId)amfUe.AttachRanUe(ranUe)}}}
4.5 AMF向UE來獲取身份信息
如果UE的上下文信息獲取失敗的話,NEW AMF只能向UE來獲取身份信息。NEW AMF向UE發送Identity Request。UE向NEW AMF返回Identity Response,發送SUPI或SUCI給NEW AMF。
協議流程的位置:
對應流程圖中step6,step7
報文捕獲:
代碼實現:
定位到free5gc amf項目/amf/ngap/handler.go中的AuthenticationProcedure函數
func AuthenticationProcedure(ue *context.AmfUe, accessType models.AccessType) (bool, error) {ue.GmmLog.Info("Authentication procedure")
// 判斷ue有沒有SUCI或SUPIif IdentityVerification(ue) {ue.GmmLog.Debugln("UE has SUCI / SUPI")if ue.SecurityContextIsValid() {ue.GmmLog.Debugln("UE has a valid security context - skip the authentication procedure")return true, nil}} else {// 如果沒有,amf向ue發送identity request消息,獲取SUCIgmm_message.SendIdentityRequest(ue.RanUe[accessType], nasMessage.MobileIdentity5GSTypeSuci)return false, nil}
4.6 AUSF Selection
NEW AMF基于獲取的SUPI或SUCI信息來選擇一個AUSF,為用戶執行接入認證。
協議流程的位置:
對應流程圖中step8
報文捕獲:
代碼實現:
定位到free5gc amf項目/amf/ngap/handler.go中AuthenticationProcedure函數
// 基于SUCI來選擇AUSF網元param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{}resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_AUSF, models.NfType_AMF, ¶m)if err != nil {ue.GmmLog.Error("AMF can not select an AUSF by NRF")return false, err}
4.7 執行鑒權
開始執行鑒權流程(Authentication Security),AUSF向UDM發起鑒權,獲取鑒權向量,完成鑒權流程。詳細的5G-AKA鑒權流程分析見文章《基于UERANSIM+free5gc 5G模擬環境的5G_AKA協議解析》。
協議流程的位置:
對應流程圖中step9
報文捕獲:
4.8 New AMF通知Old AMF,UE在New AMF注冊完成
New AMF通知Old AMF,UE在New AMF注冊完成。
協議流程的位置:
對應流程圖中step10
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的HandleInitialRegistration函數
if ue.ServingAmfChanged {//如果AMF發生了變化,New AMF會通知Old AMF,UE在New AMF注冊已完成。req := models.UeRegStatusUpdateReqData{TransferStatus: models.UeContextTransferStatus_TRANSFERRED,}
regStatusTransferComplete, problemDetails, err := consumer.RegistrationStatusUpdate(ue, req)if problemDetails != nil {ue.GmmLog.Errorf("Registration Status Update Failed Problem[%+v]", problemDetails)} else if err != nil {ue.GmmLog.Errorf("Registration Status Update Error[%+v]", err)} else {if regStatusTransferComplete {ue.GmmLog.Infof("Registration Status Transfer complete")}}}
4.9 UDM Selection
鑒權流程結束后,AMF觸發UDM選擇。其中NRF向AMF返回報文
協議流程的位置:
對應流程圖中step13
報文捕獲:
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的HandleInitialRegistration函數
if ue.ServingAmfChanged || ue.State[models.AccessType_NON_3_GPP_ACCESS].Is(context.Registered) ||!ue.ContextValid {if err := communicateWithUDM(ue, anType); err != nil {return err}}
繼續定位到free5gc amf項目/amf/gmm/handler.go中的communicateWithUDM函數
func communicateWithUDM(ue *context.AmfUe, accessType models.AccessType) error {ue.GmmLog.Debugln("communicateWithUDM")amfSelf := context.AMF_Self()
// UDM selection described in TS 23.501 6.3.8// TODO: consider udm group id, Routing ID part of SUCI, GPSI or External Group ID (e.g., by the NEF)param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{Supi: optional.NewString(ue.Supi),}//基于SUPI來選擇UDMresp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_UDM, models.NfType_AMF, ¶m)if err != nil {return fmt.Errorf("AMF can not select an UDM by NRF")}
var uecmUri, sdmUri stringfor _, nfProfile := range resp.NfInstances {ue.UdmId = nfProfile.NfInstanceIduecmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_UECM, models.NfServiceStatus_REGISTERED)sdmUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NUDM_SDM, models.NfServiceStatus_REGISTERED)if uecmUri != "" && sdmUri != "" {break}}ue.NudmUECMUri = uecmUriue.NudmSDMUri = sdmUriif ue.NudmUECMUri == "" || ue.NudmSDMUri == "" {return fmt.Errorf("AMF can not select an UDM by NRF")}
4.10 注冊 Nudm_UECM_registration
AMF向UDM發起注冊請求
協議流程的位置:
對應流程圖中step14a
報文捕獲:
UDM返回201Created,注冊成功。
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的communicateWithUDM函數
problemDetails, err := consumer.UeCmRegistration(ue, accessType, true)if problemDetails != nil {ue.GmmLog.Errorf("UECM_Registration Failed Problem[%+v]", problemDetails)} else if err != nil {ue.GmmLog.Errorf("UECM_Registration Error[%+v]", err)}
接著查看free5gc amf項目/amf/consumer/ue_context_management.go中UeCmRegistration函數
func UeCmRegistration(ue *amf_context.AmfUe, accessType models.AccessType, initialRegistrationInd bool) ( *models.ProblemDetails, error) { configuration := Nudm_UEContextManagement.NewConfiguration() configuration.SetBasePath(ue.NudmUECMUri) client := Nudm_UEContextManagement.NewAPIClient(configuration)
amfSelf := amf_context.AMF_Self()
switch accessType { case models.AccessType__3_GPP_ACCESS: registrationData := models.Amf3GppAccessRegistration{ AmfInstanceId: amfSelf.NfId, InitialRegistrationInd: initialRegistrationInd, Guami: &amfSelf.ServedGuamiList[0], RatType: ue.RatType, // TODO: not support Homogenous Support of IMS Voice over PS Sessions this stage ImsVoPs: models.ImsVoPs_HOMOGENEOUS_NON_SUPPORT, }
_, httpResp, localErr := client.AMFRegistrationFor3GPPAccessApi.Registration(context.Background(), ue.Supi, registrationData) if localErr == nil { //返回注冊成功 ue.UeCmRegistered = true return nil, nil } else if httpResp != nil { if httpResp.Status != localErr.Error() { return nil, localErr } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) return &problem, nil } else { return nil, openapi.ReportError("server no response") } case models.AccessType_NON_3_GPP_ACCESS: //下面是針對非3gpp場景 registrationData := models.AmfNon3GppAccessRegistration{ AmfInstanceId: amfSelf.NfId, Guami: &amfSelf.ServedGuamiList[0], RatType: ue.RatType, }
_, httpResp, localErr := client.AMFRegistrationForNon3GPPAccessApi.Register(context.Background(), ue.Supi, registrationData) if localErr == nil { ue.UeCmRegistered = true return nil, nil } else if httpResp != nil { if httpResp.Status != localErr.Error() { return nil, localErr } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) return &problem, nil } else { return nil, openapi.ReportError("server no response") } }
return nil, nil}
4.11 獲取 Nudm_SDM_Get
AMF向UDM獲取am-data數據、smf-select-data數據和ue-context-in-smf-data數據。
協議流程的位置:
對應流程圖中step14b
報文捕獲:
獲取am-data數據
返回200 OK
獲取smf-select-data數據

返回200 ok
獲取ue-context-in-smf-data數據
返回200 ok
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的communicateWithUDM函數
problemDetails, err = consumer.SDMGetAmData(ue) if problemDetails != nil { ue.GmmLog.Errorf("SDM_Get AmData Failed Problem[%+v]", problemDetails) } else if err != nil { return fmt.Errorf("SDM_Get AmData Error[%+v]", err) }
problemDetails, err = consumer.SDMGetSmfSelectData(ue) if problemDetails != nil { ue.GmmLog.Errorf("SDM_Get SmfSelectData Failed Problem[%+v]", problemDetails) } else if err != nil { return fmt.Errorf("SDM_Get SmfSelectData Error[%+v]", err) }
problemDetails, err = consumer.SDMGetUeContextInSmfData(ue) if problemDetails != nil { ue.GmmLog.Errorf("SDM_Get UeContextInSmfData Failed Problem[%+v]", problemDetails) } else if err != nil { return fmt.Errorf("SDM_Get UeContextInSmfData Error[%+v]", err) }
4.12 訂閱 Nudm_SDM_Subscribe
AMF向UDM發送訂閱請求,UDM需要保存注冊的AMF信息。
協議流程的位置:
對應流程圖中step14c
報文捕獲:
返回201 Created,訂閱成功。
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的communicateWithUDM函數
problemDetails, err = consumer.SDMSubscribe(ue) if problemDetails != nil { ue.GmmLog.Errorf("SDM Subscribe Failed Problem[%+v]", problemDetails) } else if err != nil { ue.GmmLog.Errorf("SDM Subscribe Error[%+v]", err) return fmt.Errorf("SDM Subscribe Error[%+v]", err) }
接著查看free5gc amf項目/amf/consumer/subscriber_data_management.go中的SDMSubscribe函數
func SDMSubscribe(ue *amf_context.AmfUe) (problemDetails *models.ProblemDetails, err error) { configuration := Nudm_SubscriberDataManagement.NewConfiguration() configuration.SetBasePath(ue.NudmSDMUri) client := Nudm_SubscriberDataManagement.NewAPIClient(configuration)
amfSelf := amf_context.AMF_Self() sdmSubscription := models.SdmSubscription{ NfInstanceId: amfSelf.NfId, PlmnId: &ue.PlmnId, }
resSubscription, httpResp, localErr := client.SubscriptionCreationApi.Subscribe( context.Background(), ue.Supi, sdmSubscription) if localErr == nil { //UDM向AMF返回訂閱信息 ue.SdmSubscriptionId = resSubscription.SubscriptionId return } else if httpResp != nil { if httpResp.Status != localErr.Error() { err = localErr return } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) problemDetails = &problem } else { err = openapi.ReportError("server no response") } return}
最后UDM向Old AMF發送注銷消息,Old AMF刪除MM上下文,對應step14d,step14e
4.13 PCF Selection
AMF觸發PCF選擇(PCF selection)
協議流程的位置:
對應流程圖中step15
報文捕獲:
代碼實現:
定位到free5gc amf項目/amf/gmm/handler.go中的HandleInitialRegistration函數
param := Nnrf_NFDiscovery.SearchNFInstancesParamOpts{ Supi: optional.NewString(ue.Supi), } for { resp, err := consumer.SendSearchNFInstances(amfSelf.NrfUri, models.NfType_PCF, models.NfType_AMF, ¶m) if err != nil { ue.GmmLog.Error("AMF can not select an PCF by NRF") } else { // select the first PCF, TODO: select base on other info var pcfUri string for _, nfProfile := range resp.NfInstances { pcfUri = util.SearchNFServiceUri(nfProfile, models.ServiceName_NPCF_AM_POLICY_CONTROL, models.NfServiceStatus_REGISTERED) if pcfUri != "" { ue.PcfId = nfProfile.NfInstanceId break } } if ue.PcfUri = pcfUri; ue.PcfUri == "" { ue.GmmLog.Error("AMF can not select an PCF by NRF") } else { break } } time.Sleep(500 * time.Millisecond) // 如果NF接口獲取失敗這里增加一段延時
4.14 獲取接入和移動策略控制信息AMPolicyControlCreate
AMF 執行AM Policy Association Establishment/Modification,獲取接入和移動策略控制信息
協議流程的位置:
對應流程圖中step16
報文捕獲:
返回201 Created
代碼實現:
定位到free5gc amf項目/amf/consumer/am_policy.go中的AMPolicyControlCreate函數
func AMPolicyControlCreate(ue *amf_context.AmfUe, anType models.AccessType) (*models.ProblemDetails, error) { configuration := Npcf_AMPolicy.NewConfiguration() configuration.SetBasePath(ue.PcfUri) client := Npcf_AMPolicy.NewAPIClient(configuration)
amfSelf := amf_context.AMF_Self()
policyAssociationRequest := models.PolicyAssociationRequest{ NotificationUri: amfSelf.GetIPv4Uri() + "/namf-callback/v1/am-policy/", Supi: ue.Supi, Pei: ue.Pei, Gpsi: ue.Gpsi, AccessType: anType, ServingPlmn: &models.NetworkId{ Mcc: ue.PlmnId.Mcc, Mnc: ue.PlmnId.Mnc, }, Guami: &amfSelf.ServedGuamiList[0], }
if ue.AccessAndMobilitySubscriptionData != nil { policyAssociationRequest.Rfsp = ue.AccessAndMobilitySubscriptionData.RfspIndex }
res, httpResp, localErr := client.DefaultApi.PoliciesPost(context.Background(), policyAssociationRequest) if localErr == nil { locationHeader := httpResp.Header.Get("Location") logger.ConsumerLog.Debugf("location header: %+v", locationHeader) ue.AmPolicyUri = locationHeader
re := regexp.MustCompile("/policies/.*") match := re.FindStringSubmatch(locationHeader)
ue.PolicyAssociationId = match[0][10:] ue.AmPolicyAssociation = &res
if res.Triggers != nil { for _, trigger := range res.Triggers { if trigger == models.RequestTrigger_LOC_CH { ue.RequestTriggerLocationChange = true } //if trigger == models.RequestTrigger_PRA_CH { // TODO: Presence Reporting Area handling (TS 23.503 6.1.2.5, TS 23.501 5.6.11) //} } }
logger.ConsumerLog.Debugf("UE AM Policy Association ID: %s", ue.PolicyAssociationId) logger.ConsumerLog.Debugf("AmPolicyAssociation: %+v", ue.AmPolicyAssociation) } else if httpResp != nil { if httpResp.Status != localErr.Error() { return nil, localErr } problem := localErr.(openapi.GenericOpenAPIError).Model().(models.ProblemDetails) return &problem, nil } else { return nil, openapi.ReportError("server no response") } return nil, nil}
4.15 更新SM上下文消息
AMF向SMF發送通知消息,更新SM上下文消息。
協議流程的位置:
對應流程圖中step17
說明:
當注冊類型為移動性注冊更新,該步驟才應用,故不涉及。
4.17 N2 AMF Mobility Request
對于非3gpp接入的場景,AMF向N3IWF發送通知消息,告知AMF發生了變化,N3IWF向AMF返回了響應。
協議流程的位置:
對應流程圖中step18,step19
說明:
不支持
// TODO (step 18 optional):// If the AMF has changed and the old AMF has indicated an existing NGAP UE association towards a N3IWF, the new AMF// creates an NGAP UE association towards the N3IWF to which the UE is connectedsend N2 AMF mobility request to N3IWF// if anType == models.AccessType_NON_3_GPP_ACCESS && ue.ServingAmfChanged {// TODO: send N2 AMF Mobility Request
4.18 Registration accept
AMF給UE發送Registration Accept消息
協議流程的位置:
對應流程圖中step21
報文捕獲:

4.19 Registration Compelte
UE給AMF發送Registration Complete消息,通知AMF注冊完成。
協議流程的位置:
對應流程圖中step22
報文捕獲:

代碼實現:
AMF處理HandleUplinkNasTransport,定位到free5gc amf項目/amf/ngap/handler.go中的HandleUplinkNasTransport函數
func HandleUplinkNasTransport(ran *context.AmfRan, message *ngapType.NGAPPDU) { var aMFUENGAPID *ngapType.AMFUENGAPID var rANUENGAPID *ngapType.RANUENGAPID var nASPDU *ngapType.NASPDU var userLocationInformation *ngapType.UserLocationInformation
if ran == nil { logger.NgapLog.Error("ran is nil") return } if message == nil { ran.Log.Error("NGAP Message is nil") return }
initiatingMessage := message.InitiatingMessage if initiatingMessage == nil { ran.Log.Error("Initiating Message is nil") return }
uplinkNasTransport := initiatingMessage.Value.UplinkNASTransport if uplinkNasTransport == nil { ran.Log.Error("UplinkNasTransport is nil") return } ran.Log.Info("Handle Uplink Nas Transport")
for i := 0; i < len(uplinkNasTransport.ProtocolIEs.List); i++ { ie := uplinkNasTransport.ProtocolIEs.List[i] switch ie.Id.Value { case ngapType.ProtocolIEIDAMFUENGAPID: aMFUENGAPID = ie.Value.AMFUENGAPID ran.Log.Trace("Decode IE AmfUeNgapID") if aMFUENGAPID == nil { ran.Log.Error("AmfUeNgapID is nil") return } case ngapType.ProtocolIEIDRANUENGAPID: rANUENGAPID = ie.Value.RANUENGAPID ran.Log.Trace("Decode IE RanUeNgapID") if rANUENGAPID == nil { ran.Log.Error("RanUeNgapID is nil") return } case ngapType.ProtocolIEIDNASPDU: nASPDU = ie.Value.NASPDU ran.Log.Trace("Decode IE NasPdu") if nASPDU == nil { ran.Log.Error("nASPDU is nil") return } case ngapType.ProtocolIEIDUserLocationInformation: userLocationInformation = ie.Value.UserLocationInformation ran.Log.Trace("Decode IE UserLocationInformation") if userLocationInformation == nil { ran.Log.Error("UserLocationInformation is nil") return } } }
ranUe := ran.RanUeFindByRanUeNgapID(rANUENGAPID.Value) if ranUe == nil { ran.Log.Errorf("No UE Context[RanUeNgapID: %d]", rANUENGAPID.Value) return } amfUe := ranUe.AmfUe if amfUe == nil { err := ranUe.Remove() if err != nil { ran.Log.Errorf(err.Error()) } ran.Log.Errorf("No UE Context of RanUe with RANUENGAPID[%d] AMFUENGAPID[%d] ", rANUENGAPID.Value, aMFUENGAPID.Value) return }
ranUe.Log.Infof("Uplink NAS Transport (RAN UE NGAP ID: %d)", ranUe.RanUeNgapId)
if userLocationInformation != nil { ranUe.UpdateLocation(userLocationInformation) }
nas.HandleNAS(ranUe, ngapType.ProcedureCodeUplinkNASTransport, nASPDU.Value)}
最后定位到free5gc amf項目/amf/gmm/handler.go中的HandleRegistrationComplete函數
func HandleRegistrationComplete(ue *context.AmfUe, accessType models.AccessType, registrationComplete *nasMessage.RegistrationComplete) error { //返回注冊完成 ue.GmmLog.Info("Handle Registration Complete")
if ue.T3550 != nil { ue.T3550.Stop() ue.T3550 = nil // clear the timer }
五、總結
本文借助free5gc+UERANSIM模擬5G網絡環境,通過抓包和源碼分析的方式介紹了用戶注冊管理流程的相關步驟。希望能幫助到對5G知識感興趣的讀者,不足之處請多多指正。
參考資料
沉烽網絡安全實驗室:《free5gc+UERANSIM模擬5G網絡環境搭建及基本使用》
https://www.freebuf.com/articles/wireless/268397.html
沉烽網絡安全實驗室:《基于UERANSIM+free5gc 5G模擬環境的5G_AKA協議解析》
https://www.freebuf.com/articles/wireless/273792.html
張忠琳:【5G核心網】free5GC 注冊請求流程源碼分析
https://www.it610.com/article/1292406752595222528.htm
3GPP TS 23 502
3GPP TS 33.501
free5gc https://github.com/free5gc/free5gc
UERANSIM https://github.com/aligungr/UERANSIM