• SELinux,无semanage,Linux user到SELinux user的映射


    前提:因为不用linux用户有不一样的权限,所以需要为不用Linux用户映射为不同权限的SELinux的用户权限。又基于平台不支持semanage等工具,因此需要把SELinux用户权限直接编译到固件种。

    主要通过添加Linux用户与SELinux用户为相同名字,并为SELinux用户匹配不同的权限完成映射。


    在SELinux模式下登录用户先进行linux用户名及密码的验证,然后再为Linux用户名匹配SELinux用户的安全上下问,最后对此安全上下文是否有相关policy去允许。Linux用户与SELinux用户匹配规则通过分析libselinux.so源码(即get_context_list.c中的get_ordered_context_list函数)得知。

    1. int get_ordered_context_list(const char *user,
    2. const char *fromcon,
    3. char *** list)
    4. {
    5. char **reachable = NULL;
    6. int rc = 0;
    7. unsigned nreachable = 0;
    8. char *backup_fromcon = NULL;
    9. FILE *fp;
    10. char *fname = NULL;
    11. size_t fname_len;
    12. const char *user_contexts_path = selinux_user_contexts_path();
    13. if (!fromcon) {
    14. /* Get the current context and use it for the starting context */
    15. rc = getcon(&backup_fromcon);
    16. if (rc < 0)
    17. return rc;
    18. fromcon = backup_fromcon;
    19. }
    20. /* Determine the ordering to apply from the optional per-user config
    21. and from the global config. */
    22. fname_len = strlen(user_contexts_path) + strlen(user) + 2;
    23. fname = malloc(fname_len);
    24. if (!fname)
    25. goto failsafe;
    26. snprintf(fname, fname_len, "%s%s", user_contexts_path, user);
    27. fp = fopen(fname, "re");
    28. if (fp) {
    29. __fsetlocking(fp, FSETLOCKING_BYCALLER);
    30. rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
    31. fclose(fp);
    32. if (rc < 0 && errno != ENOENT) {
    33. fprintf(stderr,
    34. "%s: error in processing configuration file %s\n",
    35. __FUNCTION__, fname);
    36. /* Fall through, try global config */
    37. }
    38. }
    39. free(fname);
    40. fp = fopen(selinux_default_context_path(), "re");
    41. if (fp) {
    42. __fsetlocking(fp, FSETLOCKING_BYCALLER);
    43. rc = get_context_user(fp, fromcon, user, &reachable, &nreachable);
    44. fclose(fp);
    45. if (rc < 0 && errno != ENOENT) {
    46. fprintf(stderr,
    47. "%s: error in processing configuration file %s\n",
    48. __FUNCTION__, selinux_default_context_path());
    49. /* Fall through */
    50. }
    51. }
    52. if (!nreachable)
    53. goto failsafe;
    54. out:
    55. if (nreachable > 0) {
    56. *list = reachable;
    57. rc = nreachable;
    58. }
    59. else
    60. freeconary(reachable);
    61. freecon(backup_fromcon);
    62. return rc;
    63. failsafe:
    64. /* Unable to determine a reachable context list, try to fall back to
    65. the "failsafe" context to at least permit root login
    66. for emergency recovery if possible. */
    67. freeconary(reachable);
    68. reachable = malloc(2 * sizeof(char *));
    69. if (!reachable) {
    70. rc = -1;
    71. goto out;
    72. }
    73. reachable[0] = reachable[1] = 0;
    74. rc = get_failsafe_context(user, &reachable[0]);
    75. if (rc < 0) {
    76. freeconary(reachable);
    77. reachable = NULL;
    78. goto out;
    79. }
    80. nreachable = 1; /* one context in the list */
    81. goto out;
    82. }

    首先通过user_contexts_path去获取SELinux的安全上下文,如果没有获取到会再通过selinux_default_context_path路径去获取安全上下文,最后如果两个地方都没有成功会直接使用get_failsafe_context中的安全上下文。

    user_contexts_path对应的是/etc/selinux/targeted/contexts/users/,在这个目录下的查看与登录用户名相同的文件中去获取安全上下文。

     selinux_default_context_path对应的是/etc/selinux/targeted/contexts/default_contexts文件。

    cget_failsafe_context对应的是/etc/selinux/targeted/contexts/failsafe_context文件。

     除failsafe_context文件文件外,文件内容有两部分,前面一部分匹配当前登录时系统使用的规则(rule)及类型(type)。

    当匹配前面部分后,就为当前用户匹配为后面部分的规则(rule)及类型(type)。当前面两个文件中都没有匹配成功则直接使用failsafe_context文件中的规则(rule)及类型(type),因此failsafe_context文件中没有前面部分,只有后面部分的内容。匹配成功后会与policy.xx(不同的selinux版本xx的值不同)中的规则进行验证(如user root roles { system_r };),如果没有roles规则与之匹配则报错can't get SID for xxx,若有规则则登录成功。

    注意,匹配SELinux安全上下文之前Linux用户密码输入错误时是另一个报错需要与之区分。

    总结:1.在refpolicy-2.20200229/config/appconfig-standard/目录下新增XXX_default_contexts文件(XXX未新增的用户名),并在文件中配置需要的安全上下文权限(若已存在用户则直接修改或添加需要的安全上下文权限)。或在refpolicy-2.20200229/config/appconfig-standard/default_contexts文件中直接修改或添加需要的安全上下文权限。

    2.在refpolicy-2.20200229/policy/users源码中添加对应的gen_user规则。

    例如:添加用户名为ethan的安全上下文为ethan:system_r:kernel_t的SELinux用户

     修改并编译后登录验证:

     

     

     

  • 相关阅读:
    SpringCloud原理-OpenFeign篇(三、FeignClient的动态代理原理)
    数组13— forEach() :遍历数组元素
    基于遗传优化的货柜货物摆放优化问题求解matlab仿真
    Ardupilot — AP_OpticalFlow代码梳理
    SpringBoot概述
    算法设计与分析双击调度自写
    深入探究 Java 虚拟机(JVM)中的栈(Stack)和堆(Heap)
    HTML经典布局方式
    Windows网络与通信程序设计实验四:基于WSAEventSelect模型的通信仿真
    java计算机毕业设计高校招生管理系统源码+数据库+系统+lw文档+部署
  • 原文地址:https://blog.csdn.net/qq_41133610/article/details/126055619