刚接触5G核心网那会儿我被UE开机后的那串信令绕得晕头转向注册、鉴权、安全模式、PDU会话消息一封接一封每一封都在UE和AMF之间来回。后来把Wireshark打开看到一条Registration Request在协议树里一层层展开很多协议字段才真正对上号。这篇就围绕5G核心网里的NAS消息解析从协议字段讲起再落到Wireshark的实际抓包演示适合正在学5G协议、做核心网测试或者准备从LTE转5G的朋友。1. NAS消息在5G信令面里的位置以及为什么值得专门抓它1.1 NAS到底干的是什么活NAS是非接入层Non-Access Stratum翻译成人话就是它不属于某个基站或某条无线链路而是在UE和核心网之间“端到端”交互的信令。4G里有APN、Attach那一套5G里换成了一整套新的NAS流程但核心思路一致终端要和网络完成身份校验、安全协商、注册、会话建立这些动作基本都靠NAS消息承载。5G的NAS又分成两个子层5GMM5G Mobility Management管移动性比如注册、去注册、服务请求、TAU之类的流程都是它的事。5GSM5G Session Management管会话比如PDU会话的建立、修改、释放跟数据连接密不可分。这两层消息在抓包里很容易区分因为它们的 Extended Protocol Discriminator 不一样5GMM是0x7E5GSM是0x2E。只要看到Wireshark协议树里展开的NAS-5GS就说明这层已经到了核心网用户面的“大脑”了。1.2 为什么非要抓NAS直接看RRC和NGAP不行吗NAS本身是放在空口的RRC消息里或者N2口的NGAP消息里传到核心网的。所以理论上只看RRC或者NGAP也能看到一部分信息但你看到的多半是“壳子”——比如RRCConnectionSetupComplete里裹着一条NAS消息但你不知道里面具体是注册请求还是PDU会话相关更看不到SUCI、GUTI、NSSAI这些关键字段。NAS消息相当于一个“信封”把移动性管理和会话管理的具体内容装在里面。排障的时候如果UE注册不上最常见的动作就是到N2口抓一条NGAP消息展开里面那个 NAS-PDU 字段看里面的NAS层到底报了什么原因。这个动作我做过无数遍可以说是5G核心网排障里最基础也最有效的一招。再有一个重要原因NAS消息里藏着网络选择、安全参数、切片信息这些核心网的核心决策。比如Registration Request里的Requested NSSAI直接决定了用户能不能用某个网络切片PDU Session Establishment Request里的DNN和SSC mode又决定了数据会话怎么建立。不懂这些字段光看接口告警根本定位不了问题。1.3 明文还是密文决定了你能看到什么NAS有一个特别容易把人劝退的点消息分明文和受保护两种状态。Wireshark里看Security Header Type0就是明文非0就是完整性保护或加密保护。在真实商用网络里注册流程走到Security Mode Command之后NAS消息基本就加密了抓包看到后面一堆乱码很正常。这也是为什么我特别推荐用模拟环境来学NAS解析在Open5GS加UERANSIM这套组合里可以把安全算法配成NEA0/NIA0让安全模式建立后的消息也保持明文。这样一来完整流程的每一条NAS都能在Wireshark里逐字段拆开看学习效率比对着规范硬啃高得多。后面第4部分我会给出具体做法。2. 先背熟这套NAS协议字段抓包才看得懂2.1 先看懂NAS的“信封”EPD、Security Header Type、Message Type每一段5G NAS消息头三个字节几乎是必看的。第一个字节是Extended Protocol DiscriminatorEPD用来说明这段消息到底是5GMM还是5GSM或者其它协议。第二个字节里的低4位是Security Header Type高4位是Spare通常为0。第三字节就是Message Type也就是消息类型编号。我平时分析裸字节流时基本只看前三个字节就能判断这段消息大概是什么。比如0x7E 0x00 0x01就是5GMM的Registration Request明文。0x7E 0x00 0x02就是Registration Accept。0x2E 0x00 0xC1就是5GSM的PDU Session Establishment Request。这个习惯在调试接口报文时特别有用。有时候Wireshark没有自动解析出NAS层你就得自己从字节流里找到NAS的起始位置然后靠前三个字节手动识别。Security Header Type的取值也很关键在Wireshark里通常会显示成字符串比如 Plain NAS, not security protected。规范里的含义大概是Security Header Type含义0明文未受保护1完整性保护2完整性和机密性保护3完整性保护的新安全上下文4完整性和机密性保护的新安全上下文实际抓包时Registration Request刚启动时经常是0等到Security Mode Command完成后后续消息就可能变成1或2。如果你发现某条NAS消息看不懂先看一眼Security Header Type别急着怀疑解析器坏了。2.2 5GMM消息类型速查表NAS层消息类型非常多但日常定位问题最常碰到的是注册和服务请求相关的那些。这张表我建议直接存下来抓包看到就能立刻反应出来是谁发给谁的消息类型消息代码方向主要用途Registration request0x01UE → AMF初始注册、移动性更新、周期更新、紧急注册Registration accept0x02AMF → UE接受注册下发给用户相关的GUTI、TAI list、NSSAI等Registration complete0x03UE → AMF确认收到GUTI等参数Registration reject0x04AMF → UE拒绝注册带Reject causeDeregistration request (UE orig)0x05UE → AMFUE主动去注册Deregistration accept (UE orig)0x06AMF → UEUE去注册确认Deregistration request (network orig)0x07AMF → UE网络侧踢用户下线Deregistration accept (network orig)0x08UE → AMF用户确认下线Service request0x0CUE → AMFUE触发服务请求比如回数据或发信令Service accept0x0EAMF → UE网络放通服务请求Service reject0x0DAMF → UE网络拒绝服务请求Identity request0x1CAMF → UE网络请求UE上报身份Identity response0x1DUE → AMFUE返回身份信息Authentication request0x2CAMF → UE下发鉴权参数Authentication response0x2DUE → AMFUE响应鉴权结果Authentication failure0x2EUE → AMF鉴权失败Authentication result0x2FAMF → UE告知鉴权结果Security mode command0x3CAMF → UE激活安全上下文协商算法Security mode complete0x3DUE → AMFUE确认安全模式完成Security mode reject0x3EUE → AMFUE拒绝安全模式Wireshark里过滤的话可以直接用nas-5gs.message_type 0x01只看Registration Request。这比在info列里人肉筛选快得多。2.3 Registration Request / Accept 的关键字段抓包必看Registration Request是整个5G注册流程里信息量最大的一条。我拆包的时候会重点看这几个字段5GS Registration Type告诉网络这次是初始注册、移动性更新注册、周期注册还是紧急注册。初始注册值是1移动性更新是2周期更新是3。ngKSINAS密钥集标识用来标识当前NAS安全上下文是哪一套。5GS Mobile Identity这是重中之重。首次注册时可能是SUCI用来保护用户身份非首次注册时多数是5G-GUTI方便网络按上下文找回用户。UE Security CapabilityUE支持哪些加密和完整性算法。比如5G-EA里支持NEA0、128-NEA1、128-NEA2、128-NEA35G-IA里支持NIA0、128-NIA1、128-NIA2、128-NIA3。网络之后下发的Security Mode Command会从这里选算法。Requested NSSAIUE请求的切片列表。每个S-NSSAI由SST切片类型和SD切片区分符组成。这个字段直接影响核心网为这个用户分配哪个切片。PDU Session Status告诉网络当前UE侧有哪些PDU会话还活着。做注册更新时这个字段能帮网络回收状态。Registration Accept的字段则体现了“网络给用户发了什么配置”5GS Registration Result标记注册是否成功以及是否切了NSSAI。TAI List给UE分配的跟踪区列表UE在这个范围内移动时做小区更新可以不重新注册。5G-GUTI网络给UE重新分配的临时身份后续消息里就不再携带SUCI了。Allowed NSSAI网络允许UE使用的切片集合。Equivalent PLMNs若UE漫游网络可能给出等效PLMN列表UE可以优先选择。排障时如果用户“注册上了但业务不通”我通常会对比Request里的Requested NSSAI和Accept里的Allowed NSSAI很多时候是切片没匹配上导致PDU会话建在了一个不合适的切片上。2.4 5GSM消息和PDU会话参数PDU会话是用户真正跑数据的通道5GSM消息里最常看的是PDU Session Establishment Request。它的Message Type是0xC1Wireshark里的过滤写法是nas-5gs.message_type 0xc1。这条消息里值得关注的有PDU Session ID会话的本地标识后面所有增删改查都靠它定位。PDU Session TypeIPv4、IPv6、IPv4v6、Ethernet还是非结构化。企业专线类业务常看到Ethernet类型。SSC Mode会话与服务连续性模式1/2/3模式对应UE移动时PDU会话保持或重建的策略。DNN也叫APN概念延续数据网络名称通常决定用户路由到哪个UPF、访问哪个外部网络。Requested QoS RulesUE请求的QoS参数包括5QI、GBR/MBR等。做视频类业务测试时这个字段能直接看出端到端QoS的预期。看这些字段的时候脑子里要有一个业务链路意识用户要开一个视频会话首先得通过注册流程进网然后发起PDU会话请求核心网根据DNN和切片信息选择UPF最终建立数据通道。每一步对应的NAS消息都不一样所以抓包要按流程串起来看不能只看单条。2.5 用“快递单”类比理解NAS消息结构我自己带新人时常用一个类比NAS消息就像一张快递单。EPD是快递公司名告诉你这个包裹归谁管5GMM还是5GSM。Security Header Type是包装方式是普通塑料袋还是加密保险箱——决定你拆开时能不能直接看到内容。Message Type是快递业务类型是同城件、国际件还是生鲜件。后面的IE就是包裹里的实际物品每个IE有自己的编号和长度就像快递单上的物品名称。一旦建立了这个框架看Wireshark协议树就是一个个“拆包裹”的过程先看快递公司再看包装然后看业务类型最后逐个解析包裹里的“物品”。这也是为什么我不建议大家死记规范里的IE顺序表而是先理解字段功能再用Wireshark对照验证。3. Wireshark抓包前的准备与三种实战场景3.1 版本选择和NAS-5GS解析器设置Wireshark对5G NAS的支持在4.0以后比较完善建议直接用4.2以上版本。老版本对NGAP和NAS-5GS的某些字段解析不全比如S-NSSAI、GUTI的显示都有可能出现偏差排查起来很别扭。装好Wireshark后先确认NAS-5GS的协议解析器已启用。默认情况下只要抓到的数据里能识别出NGAPWireshark会自动把里面的NAS-PDU作为内嵌载荷解析出来。但如果你手动跟某条SCTP流里面是裸NAS数据就需要在协议首选项里检查Edit - Preferences - Protocols - NAS-5GS确保相关选项正常。如果抓到的文件里NGAP没有自动解析可以在SCTP流上右键 - Decode As把端口38412指定为NGAP这样Wireshark就会重新解析一次NAS层就能出来了。这个小技巧在模拟环境里特别常用因为有时候SCTP头比较零散自动识别不够灵敏。另外为了让抓的包不被截断去 Edit - Preferences - Capture 里看一眼确认没有勾选 “Limit each packet to X bytes”。如果前面有人把这个关了但设了520字节那你看到的每个包都只有前520字节后面的NAS正文全丢了协议树再点也点不出来。这种情况我遇到太多次理由还五花八门最后都是这一处设置改回来。3.2 三种典型抓包场景对比NAS消息不是凭空出现的它得从某个接口出来。根据你手里的权限和网络环境抓包通常有以下几种方式场景抓包位置工具可见内容适合场景空口测试终端UE和gNB之间的Uu口测试终端加路测软件或手机内部日志空口RRC和NAS明文/密文验证端到端注册流程、业务时延核心网N2口AMF与gNB之间tcpdump/Wireshark抓SCTP 38412端口NGAP和NAS-PDU字段完整核心网侧定位注册和移动性问题开源模拟环境本机回环或docker网桥tcpdump抓loopback或虚拟网卡所有NAS明文配NEA0后学习协议、调测新功能、自动化回归现网N2口的抓包动作往往涉及生产维护流程不建议自己随便在商用环境里乱抓。如果是学习目的最推荐的就是开源模拟环境风险低还容易复现问题。3.3 常用过滤器和抓包命令我平时在模拟环境里抓N2口信令用的命令很简单tcpdump -i lo -s 0 -w ngap.pcap sctp port 38412这里的关键是-s 0表示不截断包长度。如果忘了加默认snaplen可能只保留包前一部分回头就会发现NAS字段不全冤枉得很。把抓回来的ngap.pcap拖进Wireshark后最常用的过滤条件有这些只看所有NGAP消息ngap只看NAS消息nas-5gs只看某个消息类型比如注册请求nas-5gs.message_type 0x01只看注册接受nas-5gs.message_type 0x02看某条PDU会话建立请求nas-5gs.message_type 0xc1按用户GUTI关联nas-5gs.guti ...如果用的是tshark也可以在命令行里直接过滤tshark -r ngap.pcap -Y nas-5gs.message_type 0x01 -V这样能直接看到一条Registration Request的完整协议树适合写脚本批量抓字段。4. 实操解析一条Registration Request的完整拆包过程4.1 在Open5GS UERANSIM环境里抓一次注册我建议你在本地搭一套Open5GS加UERANSIM的模拟环境。UE启动后会自动向AMF发起初始注册请求。这时候在宿主机上跑tcpdump抓loopback就能抓到完整的NGAP和NAS消息。为了保证加密消息也能明文看到可以在Open5GS的AMF配置和UERANSIM的gnb配置里把安全算法都配成NIA0/NEA0。这样从开机注册到PDU会话建立所有NAS消息都保持明文对学习协议字段非常友好。抓完包后Wireshark里执行nas-5gs你会看到一列UE和AMF之间的NAS消息时间顺序大致是Registration Request - Authentication Request/Response - Security Mode Command/Complete - Registration Accept - Registration Complete之后可能还有PDU Session Establishment相关消息。4.2 逐字段拆解Registration RequestWireshark里双击一条Registration Request展开协议树后大概是这种感觉NAS-5GS Extended protocol discriminator: 5G mobility management (126) Security header type: Plain NAS, not security protected (0) NAS message type: Registration request (0x01) 5GS registration request 5GS registration type: Initial registration (1) ngKSI: 0 5GS mobile identity Mobile identity: ... ...... UE security capability 5G-EA: 128-NEA1 128-NEA2 128-NEA3 5G-IA: 128-NIA1 128-NIA2 128-NIA3 Requested NSSAI S-NSSAI 1 SST: 1 (eMBB)我拆这种包时并不是每个字段都停下来看而是按业务目的来选。第一次注册场景我会看三件事注册类型是不是Initial身份标识是SUCI还是GUTIUE支持的安全算法有哪些。比如你看到Mobile Identity里是一个长串SUCI这说明UE这轮注册还没拿到GUTIAMF需要通过后续流程给UE下发GUTI。如果你看到的是5G-GUTI那说明UE之前注册过AMF可以用这个GUTI查上下文免掉一部分鉴权流程。Requested NSSAI字段也很关键。模拟环境里默认配一个SST1的切片通常会显示为eMBB。如果UE请求的NSSAI和AMF允许的NSSAI对不上注册请求走到后面就可能被Reject。抓包里看到这个字段基本能判断切片配置方向性问题。4.3 再看Registration Accept与后续交互Registration Accept通常跟在鉴权和安全模式之后。Wireshark里展开后重点关注5GS Registration Result显示Registration result value确认注册成功。TAI ListAMF给UE圈定的跟踪区UE在这个范围内移动不用频繁注册更新。5G-GUTIAMF分配的新临时标识UE应在Registration Complete里确认。Allowed NSSAI网络允许的切片集合。如果看到Allowed NSSAI里没有UE请求的切片那基本就是网络侧切片配置或订阅数据的问题。这时候别光盯NAS消息得去AMF的日志里查切片选择逻辑。再往后UE会回一条Registration Complete消息很短主要用来确认收到GUTI。然后UE如果想跑业务会再发起PDU Session Establishment Request进入5GSM流程。4.4 如何顺着信令流把一次注册过程串起来抓包的意义不只是看单条消息而是要看完整流程。我在Wireshark里习惯这样操作先用nas-5gs过滤出所有NAS消息。显示列里把 Time、Source、Destination、Info 显示完整。从第一条Registration Request开始按时间顺序往下刷。刷的过程中你会发现每条NAS消息的前后依赖Registration Request发出后AMF会回Authentication Request前提是AMF需要对这个用户做鉴权。鉴权通过后AMF下发Security Mode Command协商安全算法。安全上下文建立后AMF才能安全地下发Registration Accept里面带着GUTI和TAI List。UE回复Registration Complete后注册流程才彻底闭环。如果中间某条消息没出现或者出现RejectWireshark的Info列里一般会直接显示原因比如 Registration reject。这时候点进去看Cause值再回到核心网日志里定位基本能锁定问题。4.5 用tshark提取关键字段做自动化巡检除了在Wireshark界面里一条条看我还会用tshark把NAS字段提取出来做成自动化巡检脚本。比如想检查一批抓包里所有Registration Request的注册类型和UE安全算法tshark -r ngap.pcap -Y nas-5gs.message_type 0x01 -T fields \ -e frame.number \ -e nas-5gs.registration_type \ -e nas-5gs.ue_security_capability输出结果会是一个表格方便直接拉到Excel里对比多次抓包差异。这个习惯在跑回归测试时特别有用不然每次都手动打开Wireshark点来点去效率太低了。5. 常见拦路问题与排错速查5.1 抓包文件里看不到NAS解析现象打开pcap后Info列只显示NGAP不显示NAS-5GS协议树里也找不到NAS-PDU字段。原因和处理办法先确认包是通过SCTP的NGAP端口传的默认端口是38412。如果端口不对Wireshark不会自动识别。这时候选中那条SCTP流右键选择Decode As把端口指定为NGAPNAS层就会重新解析出来。如果是纯NAS数据没有NGAP封装那就直接在Decode As里指定NAS-5GS或者检查协议首选项里的NAS-5GS是否关闭了。5.2 Wireshark只显示520字节后面的内容全没了这是老生常谈但特别容易踩的坑。现象是包列表里能看到一条注册请求点开后协议树到某个字段就断了后面的IE全部缺失。原因抓包时snaplen被限制为520字节或者Wireshark捕获选项里开了“Limit each packet to X bytes”。处理办法检查 Edit - Preferences - Capture把包长度限制关掉。用tcpdump重新抓包时带-s 0表示不限制。如果已经抓完的pcap被截断了没法补回缺失字节只能重新抓。我建议每次抓包前都先确认snaplen设置尤其在生产环境或长时间后台抓包时一个小设置会浪费几个小时排查时间。5.3 注册流程后面的NAS消息全是密文现象Security Mode Command之后的消息Wireshark显示Security Header Type为2内容变成类似乱码的加密载荷。原因这是正常现象。5G网络在安全模式激活后会对NAS消息做完整性和机密性保护没密钥的抓包工具无法解密。处理办法学习环境把模拟核心网和UE的安全算法都配置成NIA0/NEA0即可看到明文。测试环境如果需要验证加解密逻辑得从核心网侧导出密钥材料但这属于专业测试工具范围一般排障用不到。在真实商用环境里NAS密文是用户隐私保护的一部分。做协议分析时记住“看到加密不代表抓错”而是流程已经进入安全状态了。5.4 长时间抓包很卡或文件巨大打不开现象跑业务压测时用Wireshark直接抓包十分钟后Wireshark卡死pcap文件几个GB。原因Wireshark把每个包都解析到UI层量大时性能撑不住。处理办法用dumpcap或tcpdump先抓原始包不要直接开Wireshark实时抓。抓包时用capture filter缩小范围只抓SCTP 38412端口或特定IP。按时间或按大小分文件保存比如tcpdump -G 60 -W 100 -w ngap_%Y%m%d_%H%M%S.pcap每分钟一个文件总共最多100个。分析时先用tshark -r过滤出NAS消息再导入Wireshark看结果避免一次性加载巨包。5.5 怎么看UDP前后两包的时间间隔这个需求在做时延分析和流控排查时经常遇到。Wireshark默认在显示列里带一个Time可以设置为frame.time_delta_displayed就是相邻显示包的时间差。如果只想筛出间隔超过某阈值的UDP包可以直接用显示过滤器udp frame.time_delta_displayed 0.05这会把显示出来的UDP包中前后间隔大于50毫秒的包过滤出来。如果是在5G用户面抓GTP-U包这招可以快速定位有没有明显的传输间隙。5.6 NAS消息的移动性和时间关联问题有时候注册流程看起来一切正常但用户在移动过程中掉线。这种情况下只抓NAS消息还不够要把AMF日志、gNB日志和Wireshark抓包时间对齐来看。我通常的做法是在Wireshark里按frame.time导出NAS消息时间戳。与AMF的注册日志按时间匹配。先看是由哪条NAS消息触发的异常比如Deregistration Request再看网络侧当时的切换或重注册状态。时间对齐这件事看起来笨但却是最可靠的分析路径。很多协议栈问题并不是单条消息格式错误而是多条消息之间的状态迁移出了岔子。6. 从抓包到排障我的一点体会NAS消息解析这件事上手门槛不在字段多而在于你能不能把一条消息放进完整的信令流程里去看。我见过不少同事能背字段表但真到排障时抓了一堆包不知道从哪里看起。我的建议很简单拿到一个pcap先别急着查细节先把nas-5gs过滤出来按时间顺序浏览一遍看流程走到的哪一步断了再从断点那一条消息的字段里找原因。如果要在模拟环境里练手我强烈建议你亲手跑通一次完整注册抓包后把Registration Request、Registration Accept、PDU Session Establishment Request三条消息的协议树截图留档。截图的过程其实就是逼自己把每个字段过一遍比只看教程效果好太多。我自己踩过最大的坑就是刚开始抓包时没注意snaplen抓回来的包只有520字节以为协议栈有问题查了一整天才发现是抓包配置的问题。从那以后我每次抓包前都会检查两件事snaplen有没有设对端口过滤有没有写对。这两点看起来不起眼但能省掉后面一大半的无效劳动。最后再分享一个小习惯抓包文件命名一定要带上时间和接口信息比如ngap_20250925_amf_lo.pcap。时间久了你就知道规范的命名比任何笔记都管用。
