简介:面向RK3576平台Android14系统的以太网802.1X认证补丁及示例工程,适合嵌入式开发者和系统集成工程师解决设备接入企业级有线网络时的安全认证问题,可广泛应用于办公室、学校、数据中心等需要严格准入控制的场景。补丁完整集成了wpa_supplicant、Connectivity、Wifi等模块的修改,使设备能够通过802.1X协议(如EAP-PEAP)完成身份校验,并附带可直接编译运行的APK demo,便于快速验证和二次开发。资源共22个文件,包含6个Java源码、4个patch补丁、3个XML配置以及demo界面截图和readme说明,整体仅121KB,结构精简清晰。已有126人学习下载。通过学习补丁中EthernetNative、SupplicantEthIfaceHal等核心类实现,开发者可快速掌握Android14以太网802.1X接入流程,并借助demo源代码构建符合企业安全策略的定制程序,显著降低适配门槛,也为后续网络功能扩展提供了参考基础。 车载、安防、工控这类Android设备一旦部署在政企环境里,网络接入认证几乎是绕不开的一道坎。前段时间我们在RK3576平台上做Android 14系统定制,客户要求有线以太网必须支持802.1X企业认证,而不是普通DHCP就能上线的模式。排查完原生代码发现,Android 14的Ethernet框架对有线网络只支持静态IP和DHCP,压根没有留802.1X安全类型的口子。这篇就记录一下我给RK3576 Android 14打以太网802.1X补丁的完整过程,包括框架改动、方案选型、编译验证和踩坑记录,给同样要做有线认证的朋友一个可参考的路子。
1. 先说清楚:这个补丁到底在解决什么问题
1.1 为什么RK3576平台需要额外处理802.1X
RK3576是Rockchip面向中高端IoT、平板、车载和边缘计算设备推出的平台,CPU算力、VPU解码和多屏输出能力都比较均衡,不少整机方案直接跑Android 14出厂。但政企园区、运营商网关、医疗终端这类场景里,有线网口通常对接华为、深信服、Cisco这些交换机的802.1X认证端口,设备插网线后要么通过MAC旁路认证,要么就必须走EAPOL协议做企业认证。
原生Android对Wi-Fi的802.1X企业认证支持很完整,但是有线以太网的安全认证却一直很弱。EthernetNetworkFactory在创建网络时只认DHCP和静态IP两种配网模式,没有EAP-PEAP、EAP-TLS这类选项。这就导致一个很尴尬的局面:Android设备在Wi-Fi下能做的企业认证,换成网线就完全使不上劲。
1.2 原生Android 14以太网栈的边界
Android 14的以太网相关代码主要放在packages/modules/NetworkStack里,由EthernetTracker、EthernetNetworkFactory、EthernetConfigStore几个类协作完成。IpConfiguration内部有一个SecurityType枚举,但默认只有NONE、WEP、PSK几个值,基本上照搬Wi-Fi的配置思路,并没有为有线场景做扩展。
实际定制时我们发现,光靠系统设置里的“以太网”菜单,连输入802.1X用户名密码的入口都没有。而且Android框架层也没有把EAPOL报文转给wpa_supplicant的通道,等于说即便上层加了用户名密码字段,服务层也不知道该怎么和交换机完成握手。所以这个补丁必须同时解决:上层配置入口、配置持久化、底层EAPOL认证通道这三个问题。
1.3 我的补丁思路概览
综合评估下来,我采用的方案是把有线网口交给wpa_supplicant的wired驱动去处理认证,而不是在EthernetNetworkFactory里重新实现一套EAPOL协议栈。这样能够复用wpa_supplicant成熟的802.1X实现,包括PEAP、MD5、TLS等EAP方法,补丁范围也相对可控。
具体拆成三块:
- 扩展
EthernetManager的IpConfiguration.SecurityType,增加802_1X枚举; - 扩展
EthernetConfigStore,把用户名、密码、CA证书、身份等内容持久化到XML配置里; - 在
EthernetNetworkFactory里识别到802.1X配置后,不再直接通过EthernetNetworkAgent建连,而是先把网卡交由wpa_supplicant管理,等认证完成后走正常网络流程。
这个思路和部分Rockchip官方补丁的做法一致,好处是上层逻辑改动少、认证协议不容易出岔子。
2. 802.1X与Android有线网络的原理对照
2.1 802.1X认证的基本流程
802.1X认证的核心是端口访问控制,把物理端口划分为受控和非受控两条通道。客户端(Supplicant)通过非受控端口发送EAPOL-Start报文,交换机和认证服务器(RADIUS)之间走标准RADIUS协议交互,最终在成功后再打开受控端口,给设备分配IP地址。
整个过程涉及三个角色:
- 客户端设备(Supplicant),也就是我们的RK3576开发板;
- 认证设备(Authenticator),也就是交换机接入端口;
- 认证服务器(Authentication Server),通常是RADIUS服务器或AC。
调试时经常看到的现象是:设备插了网线但网络图标一直打叉,或者偶尔能获取到IP但很快又断开,大多数时候都是EAPOL握手阶段卡住了。补丁里必须在Supplicant侧完整实现EAPOL状态机,才能保证稳定对接交换机。
2.2 Android 14以太网框架中安全类型的支持情况
看packages/modules/NetworkStack/src/com/android/server/ethernet/EthernetNetworkFactory.java源码可以明显感觉到,它只针对“有网线就发DHCP请求、拿不到IP就标记网络失败”这个逻辑设计。IpConfiguration在传递给EthernetNetworkAgent之前,压根不会处理任何EAP信息。
系统设置里的以太网配置界面,正常情况下只有三个选项:DHCP、静态IP、代理设置。补丁要加入的安全类型选项必须从EthernetManager接口一路穿透到设置App,再存到EthernetConfigStore里。整个链路缺一不可。
2.3 补丁中需要补的关键节点
梳理代码后,我发现补丁至少需要触及这几个关键节点:
IpConfiguration.SecurityType枚举定义;IpConfiguration的Parcel序列化与反序列化;EthernetConfigStore的XML读写逻辑;EthernetNetworkFactory的网络创建逻辑;EthernetTracker对配置变更的通知;- 系统设置里以太网配置UI。
除此之外,还需要一个和wpa_supplicant交互的入口。Android的WifiSupplicant接口可以复用,但它默认绑定的是Wi-Fi网卡名,我们需要把它扩展到以太网接口,并指定driver为wired。这一步是整个补丁里最容易出问题的地方。
3. 补丁设计与源码改动
3.1 框架层:扩展EthernetManager的SecurityType
在android.net.IpConfiguration里增加一个安全类型,等于同时修改了一个被系统多处引用的基础类。最初我尝试直接复用Wi-Fi的WifiEnterpriseConfig,把802.1X配置塞进IpConfiguration,但这样会引入对Wifi框架的强依赖,在系统服务层容易引发循环依赖或者类型转换问题。
我最后选的是轻量方案:在IpConfiguration中新增一个EnterpriseConfig内部字段,只包含身份、匿名身份、密码、CA证书路径、EAP方法这几个基础字段,够用且不会破坏原有序列化逻辑。
public static class EnterpriseConfig implements Parcelable { public String identity = ""; public String anonymousIdentity = ""; public String password = ""; public String caCertPath = ""; public int eapMethod = EapMethod.PEAP; public EnterpriseConfig() {} protected EnterpriseConfig(Parcel in) { identity = in.readString(); anonymousIdentity = in.readString(); password = in.readString(); caCertPath = in.readString(); eapMethod = in.readInt(); } @Override public void writeToParcel(Parcel dest, int flags) { dest.writeString(identity); dest.writeString(anonymousIdentity); dest.writeString(password); dest.writeString(caCertPath); dest.writeInt(eapMethod); } }SecurityType枚举里增加802_1X,并且保证Parcel读写和旧版本兼容。这样设置App就能把配置项传到系统服务层。
3.2 服务层:EthernetNetworkFactory对接802.1X配置
EthernetNetworkFactory在拿到接口配置后,原本会直接走createNetworkAgent流程。补丁里要做的是分支判断:如果安全类型是802.1X,先把网卡的IP配置清空,调用wpa_supplicant接管网卡,监听认证结果。
核心逻辑可以简化为:
if (config.getSecurityType() == IpConfiguration.SecurityType.NONE || config.getSecurityType() == IpConfiguration.SecurityType.STATIC) { // 原生逻辑,直接创建网络 } else if (config.getSecurityType() == IpConfiguration.SecurityType.DOT1X) { // 先交给wpa_supplicant处理EAPOL认证 boolean authenticated = mSupplicantBridge.startWired8021x( ifaceName, config.getEnterpriseConfig()); if (authenticated) { // 认证完成后重新走DHCP或者静态IP配置 setupNetworkAfterAuth(); } }这里有个细节:当wpa_supplicant接管网卡后,原来的EthernetNetworkFactory不能再继续监听这个网卡的link state,否则可能重复创建网络。我采用的做法是在认证期间暂停该网卡的网络候选,等认证成功后再恢复。
3.3 系统应用层:设置界面增加认证字段
原生设置里的以太网配置需要扩展,这里我用的是Settings模块的EthernetConfigActivity。补丁要增加一个安全类型下拉框,当用户选择802.1X后,把用户名、密码、CA证书、EAP方法等输入框显示出来。
界面上的字段需要和框架层的EnterpriseConfig一一对应。代码改动不复杂,但布局文件要重新整理,尤其注意横竖屏切换时保留输入状态,否则用户填一半密码切了个屏就全部丢掉了。
字段样例:
- 认证方式:PEAP / TLS / MD5
- 身份
- 匿名身份
- 密码
- CA证书路径
3.4 配置文件与IPC传递
EthernetConfigStore会把配置写入/data/misc/ethernet/ipconfig.txt。补丁必须扩展它的write()和read()方法,把新增的EnterpriseConfig一并序列化进去,否则设备重启后802.1X配置全部丢失。
序列化格式我沿用了XML结构,保证老版本配置可以正常读取,新字段缺省时按空值处理。
<ipconfig> <securityType>802_1X</securityType> <enterprise> <identity>user01</identity> <password>abcdef</password> <caCertPath>/data/misc/ethernet/ca.pem</caCertPath> <eapMethod>PEAP</eapMethod> </enterprise> <staticIpConfig /> </ipconfig>IPC层面,由于IpConfiguration已经实现了Parcelable,新增字段会自动随Binder调用传递。只注意一点:EthernetManager的接口如果是AIDL,需要在AIDL文件里确认兼容,否则服务端升级后客户端拿到的是空对象。
4. 编译、打包与验证
4.1 编译步骤
RK3576 Android 14的编译流程比较成熟,修改NetworkStack模块后不需要整包编译,可以单独编译模块后在系统镜像里替换。
source build/envsetup.sh lunch rk3576_xxx-userdebug m packages/modules/NetworkStack编译产物在out/target/product/rk3576_xxx/system/framework/下,可以用adb push推入设备,但更稳妥的做法是重打包system.img或者直接整编生成update.img刷机。毕竟框架层改动涉及系统签名,如果不刷机验证,可能会因为签名不一致导致系统服务起不来。
设置模块的改动可以单独编译Settings APK:
m Settings4.2 用wpa_supplicant和EAPOL验证
补丁编译进去后,先用简单的PEAP认证环境验证。我在内网搭了一个基于freeRADIUS的认证服务,交换机端口开启802.1X模式,然后RK3576设备通过网线接入。
设备端开启日志,观察wpa_supplicant是否成功发起EAPOL握手:
logcat -s wpa_supplicant:E正常流程会依次看到EAPOL-START、EAP-REQUEST/IDENTITY、EAP-RESPONSE、EAP-SUCCESS的日志。如果卡在某个状态,对照下面的排查表处理。
4.3 与华为/深信服交换机对接的配置要点
实际项目里客户侧的交换机大概率是华为或深信服。华为交换机配置802.1X认证时需要注意端口模式,必须设置为authentication或auto模式,不能用force-authorized,否则设备发EAPOL报文交换机根本不响应。
interface GigabitEthernet0/0/1 dot1x enable dot1x port-method portbased深信服AC配合华为交换机做802.1X认证的场景我也遇到过,这类方案通常需要交换机把RADIUS请求指向AC,设备端只是标准Supplicant。补丁里不需要针对AC做定制,只要EAPOL握手能通过,上层网络就能正常建立。
5. 踩坑记录与常见问题
5.1 ConnectivityManager网络评分导致有线网络反复连接
补丁第一个版本测试时发现,802.1X认证成功并且拿到IP后,系统网络还是会在几秒内断开重连。看日志是EthernetNetworkAgent的network score被Wi-Fi无线网络压制,导致ConnectivityService频繁切换网络。
最后的解决办法是:在认证成功后的有线网络agent上把NetworkCapabilities的NET_CAPABILITY_INTERNET和NET_CAPABILITY_NOT_VPN等能力标记完整,并将NetworkAgentInfo的score调高。如果需求明确规定有线优先,可以在EthernetTracker里固定score为80以上。
5.2 认证成功但拿不到IP
这个坑很隐蔽。wpa_supplicant认证成功后,交换机会打开受控端口,但如果网卡的DHCP客户端没有重新触发,设备会一直停留在已认证但无IP的状态。补丁里必须在收到EAP-SUCCESS事件后主动调用DHCP重新协商。
我采用的方式是监听wpa_supplicant的状态轮询,当状态从COMPLETED切回INACTIVE时,调用EthernetNetworkFactory的配置更新接口,让网络重新走一遍DHCP流程。
5.3 证书和CA校验问题
EAP-TLS场景必须处理CA证书路径和私钥导入。Android设置App里选择CA证书时要注意/data/misc/etherne目录的SELinux上下文,默认的ethernet_data目录没有给system_server写权限,导致保存CA证书失败。
解决方式是把证书目录的SELinux type改为和wifi证书一致,或者直接在file_contexts里增加规则。PEAP场景虽然不强制客户端证书,但服务器CA校验如果开启,也必须导入服务端根证书。
5.4 热插拔与配置持久化
设备拔网线再插回后,如果wpa_supplicant没有重新启动,EAPOL状态机会卡在DISCONNECTED。需要补丁监听网卡link状态变化,在link up时重新触发wpa_supplicant的reconnect命令。
配置持久化的问题前面提过,EthernetConfigStore不扩展的话,重启后配置丢失。这个问题测试时特别容易忽视,因为第一次开机配置后看起来都正常,重启后才暴露。
5.5 配合RTL8111等USB有线网卡时的驱动时序
RK3576平台上如果外接USB转千兆网卡,比如RTL8111/RTL8153,插入瞬间的网卡枚举时序可能比系统服务初始化慢。EthernetNetworkFactory在初始化时会扫描已有网卡,如果此时USB网卡还没ready,后续插上时不会自动加入管理列表。
补丁需要在DeviceStateListener或者网卡热插拔回调里动态添加新网卡,另外wpa_supplicant的wired接口也不能提前绑定一个不存在的网卡名,否则启动直接报错。这个问题的典型现象是:上电开机后网线灯亮但系统里看不到有线网络,拔插一次网线或重新插拔USB网卡又能恢复。
补丁开发过程中最深的体会是:Android的以太网栈虽然看起来简单,但一旦牵扯到802.1X认证,就不再是“设置里加个开关”这么简单。它要求你把上层配置、服务层网络管理、底层Supplicant状态机整个链路打通,任何一环缺失都会导致认证失败或网络不稳定。如果你也在给RK3576或者其他Android 14平台做有线企业认证,建议先梳理清楚原生Ethernet模块的调用链,再动工改代码。我踩过的几个大坑已经列在上面了,照着排查能省不少时间。最后再补充一点:有条件的话,最好在真实交换机上做一轮完整的EAP-PEAP和EAP-TLS测试,模拟器和普通家用路由器验证不了边界情况。
本文还有配套的精品资源,点击获取