Do any hardened Linux distributions exist? - eviltoast
    • ctr1@fl0w.cc
      link
      fedilink
      English
      arrow-up
      1
      ·
      edit-2
      1 year ago

      Awesome! Here are a few things that come to mind:


      Make sure you have some aliases/functions for common operations:

      • audit2allow -a to view audit violations (or -d for dmesg audits)
        • also -r to add a requires statement for module construction
      • restorecon -Rv to recursively apply file contexts from policy (or -FRv to also apply user context)
      • rm -f /var/log/audit/audit.log.*; >/var/log/audit/audit.log to clear audit logs
        • note: sometimes lots of logfiles (audit.log.1, etc.) collect, slowing down audit2allow
      • chown -R user:user PATH; chcon -R -u user_u PATH to recursively change labels to user
        • could be generalized for arbitrary Linux/SELinux users
      • semanage fcontext -a -t TYPE PATH -s $SEUSER to add a custom file context to the policy
        • e.g. semanage fcontext -a -t "user_secrets_t" "/home/[^/]+/.secrets(/.*)?" -s user_u
        • I’ve had better luck with this approach than the standard method of creating a .fc file, but in any case a custom policy is needed to create custom types
      • semanage fcontext -d PATH to remove a custom file context
      • semanage fcontext -lC to list custom file contexts
      • semodule -DB to rebuild policy with all dontaudit rules disabled
        • often, something will not work, but audit2allow doesn’t show anything
      • semodule -B to rebuild policy (with dontaudit rules)
      • semodule -i MODULE.pp to install a module
      • semodule -r MODULE to remove a module

      Also a few scripts for policy creation and management are essential. There are two basic approaches to policy creation: modules and policy modules.


      Modules: can be used to modify AVC rules and are pretty simple

      # a violation has occurred that you want to allow or dontaudit
      echo "module my_allow 1.0;" > my_allow.te
      audit2allow -ar >> my_allow.te
      
      # verify that my_allow.te has what you expect
      cat my_allow.te
      
      # build and install the module (replace mcs with whatever policy you are using)
      make -f /usr/share/selinux/mcs/include/Makefile my_allow.pp
      semodule -i my_allow.pp
      
      # clear audit logs
      rm -f /var/log/audit/audit.log.*; >/var/log/audit/audit.log
      

      Policy modules: can do anything, but are complicated, and the tools for creating them are mostly based on Red Hat.

      Creating a new type:

      # generate foo.fc, foo.if, and foo.te
      sepolicy generate --newtype -t foo_var_lib_t -n foo
      
      # note: see sepolicy-generate(8); sepolicy generate only supports the following
      #       type suffixes, but its output files can be adapted to your use case
      # _tmp_t
      # _unit_file_t
      # _var_cache_t
      # _var_lib_t
      # _var_log_t
      # _var_run_t
      # _var_spool_t
      # _port_t
      
      # modify the .fc file with the desired file contexts, for example (with s0 for mcs)
      # /path/to/context/target	--	gen_context(system_u:object_r:type_t,s0)
      #
      # note: the "--" matches regular files, -d for directories, -c for character
      #       devices, -l for symbolic links, -b for block devices, or can be omitted
      #       to match anything. also, as mentioned before, I often have better luck
      #       with `semanage fcontext`, especially for user directories
      vi foo.fc
      
      # build and install the policy module
      make -f /usr/share/selinux/mcs/include/Makefile foo.pp
      semodule -i foo.pp
      
      # use restorecon to adjust the file contexts of any paths you have 
      
      # by default, all operations involving this type will be denied
      # (and are sometimes not audited)
      semodule -DB # --disable_dontaudit
      # ... use the type, collect violations ...
      audit2allow -ar >> foo.te
      # if dontaudit is disabled, you'll likely have a lot things to remove from here
      vi foo.te
      
      # ... repeat until rules regarding type are fully defined
      

      Creating a new application type:

      # sepolicy-generate is made for Red Hat,
      # but you can use --application to get started
      
      # creates a bunch of files that define bar_t and bar_exec_t
      sepolicy generate --application -n bar [-u USER] CMD
      
      # remove the line making the app permissive (up to you, but
      # I prefer using audit violations to define the permissions)
      perl -i -00 -pe 's/^permissive bar_t;\n\n//g' bar.te
      
      # ensure that the file bar_exec_t file context points to the right bin:
      vi bar.fc
      
      # build and install the policy module
      make -f /usr/share/selinux/mcs/include/Makefile bar.pp
      semodule -i bar.pp
      
      # ... use the application, update AVC rules, repeat ...
      

      If your target application is interpreted, you’ll need to write a custom C program that launches the interpreter in a specific context, then write your policy around that application. For example, you should execv something like this: /usr/bin/runcon -u user_u -t my_script_t /bin/bash PROG.