1. SEAndroid 功能简介
Seandroid:全称Security Enhancrmeints for Andriod,以SElinux为核心。使android系统支持强制访问控制以增强系统安全性。在SELinux出现之前,安全模型叫DAC,全称Discretionary Access Control即自主访问控制,但是这样的访问控制很容易获得root权限,可以做在系统中做任何事情,显得太过宽松,一种新的模型叫MAC即Mandatory Access Control 强制访问控制,它的思想就是任何进程想在系统中做任何事情,都必须在安全策略配置文件中赋予权限,凡是没有出现在安全策略配置文件的权限,进程就没有该权限。在自制安全策略中我们要最求最小权限的原则,下面以一个自制一个app特殊权限为例介绍一下SEAndroid的功能和策略。
要想制定一个app的自定义权限,我们要先了解在SEAndroid中权限赋予的方法,在SEAndroid中,我们赋予进程权限的时候都是对这个权限所在的domain赋予权限,那么就是说我们要对自己的app赋予权限的时候要在最小权限的原则下,在不影响其他进程的权限的前提下使得自己的app进程在一个自定义的domain中。
2. SEAndroid 分类
SELinux(或SEAndroid)将app划分为主要三种类型(根据user不同,也有其他的domain类型):
1)untrusted_app第三方app,没有Android平台签名,没有system权限
2)platform_app有android平台签名,没有system权限
3)system_app有android平台签名和system权限
从上面划分,权限等级,理论上:untrusted_app 从上面的划分可以看出现有的android系统中,app进程的domain主要就是这三种,如果让我们的app进程工作在这些domain中要赋予自定义的权限必然对所有domain中的进程都有影响,这显然违背了最小权限的原则,这时候我们要自定义一个domain,然后让自己的app进程工作在这个domain中,我们再对这个domain赋予自定义权限。 3. SEAndroid中app对应的te文件: system_app -> external\sepolicy\system_app.te untrusted_app-> external\sepolicy\untrusted_app.te platform_app -> external\sepolicy\platform_app.te 对应的权限,通过allow语句给予,比如只有system_app才可以设置prop: 在引入SEAndroid后,app开发需要注意需要哪些权限,根据配置(shareuid和签名)来决定domain,从而决定权限大小。通过这段时间的实验和验证以及查阅资料,发现对于应用的权限的设置、管理、修改等,都是在domain的基础上进行,单个的应用去修改权限之类的不太容易去实现,按照SEAndroid的思想,如果想给单独的一个应用去赋予特殊的权限服务。 4. 自定义应用的自定义权限配置: 下面开始介绍如何配置一个自定义应用的自定义权限,共有七个步骤: ①、要想产生一个新的domain必须给相应的app一个特定的签名,现在我们要产生一个自己的签名。 在尝试做一个自己特定的APPdomain的时候需要给自己的APP签名,签名需要用到秘钥,如果没有自己的秘钥,只能使用Android自带的秘钥,但是这时候你的APP只能运行在Android系统指定的domain中,这样的话自己的APP又不能运行在自己特定的domain中了,这样不能够在不影响其他APP的情况下来制定自己的权限设置,现在这里介绍一下可以使用Android源码树中自带的工具“development/tools/make_key”来生成带密码的RSA公私钥对(实际上是通过openssl来生成的): $ development/tools目录下有一个make_key工具,输入以下格式的命令可以产生自己的秘钥: 命令格式: 这样就会在当前目录下产生一个二进制形式(DER)的私钥文件“mykey.pk8”和一个对应的X509公钥证书文件“mykey.x509.pem”。其中,/C表示“Country Code”,/ST表示“State or Province”,/L表示“City or Locality”,/O表示“Organization”,/OU表示“Organizational Unit”,/CN表示“Name”。前面的命令生成的RSA公钥的e值为3,可以修改development/tools/make_key脚本来使用F4 (0×10001)作为e值(openssl genrsa的-3参数改为-f4)。 以上是秘钥的格式. ②将产生的秘钥放在:build/target/product/security下: 然后就可以把它们放在相应的秘钥储存位置了,如:build/target/product/security下: 以后就可以使用这些秘钥了。 ③把自己的秘钥添加到external/sepolicy下的keys.conf中: vi keys.conf: 添加秘钥: [@ZWDAPP] ALL :$DEFAULT_SYSTEM_DEV_CERTIFICATE/zwdapp.x509.pem 这样以后在选择签名key的时候系统可以找到相应的key 的路径。 ④加入自定义的seinfo这样以后的app应用可以通过相应的seinfo选择自己的app应用的domain : 在external/sepolicy下打开mac_permissions.xml文件: vi mac_permissions.xml :加入seinfo ⑤在external/sepolicy下产生一个新的te文件---zwdapp_app.te 同时更新seapp_context应用的安全上下文文件,在这个文件中加入mac_permissions.xml中的seinfo. zwdapp_app.te Seapp_context中添加的seinfo ⑥在external/sepolicy下执行mm 进行Android.mk 中执行insertkeys.py脚本会把signature的值用真正的证书的内容base16之后的值所替换,即让自己定义的签名有效。 ⑦执行external/sepolicy/tools下的脚本post_process_mac_perms 这个脚本可以把一个你单独想赋予seinfo的app签名用这个脚本添加进去,使用格式是: Post_process_mac_perms –s [seinfo] –d ./APK -f mac_permissions.xml 其中:seinfo是想单独赋予的seinfo实例中用zwdapp ./APK是APK的路径,实例中使用的是: out/target/product/p201/system/app/ReadFile/ReadFile.apk 这样就可以给你的app进程赋予自定义的权限了,上面的配置是为了让自己的app进程访问这个路径的文件: /sys/class/video/axis这个是一个普通应用无法使用的路径。 在配置权限之前,使用这个app进程访问该路径时会出现以下denied信息: ################################################################################### ################################################################################### ----------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- [ 690.992700@0] type=1400 audit(1420071094.200:26): avc: denied { read }for pid=6143 comm="le.readfiletest" name="axis"dev="sysfs" ino=12261 scontext=u:r:myapp_app:s0tcontext=u:object_r:sysfs_xbmc:s0 tclass=file permissive=0 [ 284.330364@0] type=1400 audit(1420070687.560:31): avc: denied { open }for pid=4832 comm="le.readfiletest"path="/sys/class/video/axis" dev="sysfs" ino=12261scontext=u:r:myapp_app:s0 tcontext=u:object_r:sysfs_xbmc:s0 tclass=filepermissive=0 [ 275.476886@0] type=1400 audit(1420070678.680:22): avc: denied { getattr} for pid=5591 comm="le.readfiletest"path="/sys/class/video/axis" dev="sysfs" ino=12261scontext=u:r:myapp_app:s0 tcontext=u:object_r:sysfs_xbmc:s0 tclass=filepermissive=0 ################################################################################### 而且是无法去读取该路径的文件信息的,因为此时的app进程工作的domain没有相关的权限,此时的app进程用ps -Z指令会发现工作在untrusted_app下,这个domain中我们不能给予访问etenforce 1路径的权限, 但是配置完上述步骤后,再次更新系统,安装apk运行的时候在setenforce 1 即工作在enforcing模式下同样可以访问该路径/sys/class/video/axis 因为此时的apk已经工作在zwdapp这个domain下了,这个domain我已经配置好相关的权限,而且此时我赋予的权限仅限于我这个app不对其他进程产生影响,符合最小权限的原则。 Ps -Z :