diff options
author | John Turner <jturner.usa@gmail.com> | 2025-08-26 02:03:35 -0400 |
---|---|---|
committer | John Turner <jturner.usa@gmail.com> | 2025-08-26 02:07:41 -0400 |
commit | 52a2cae0b3583d4148cbc183f6ce551f94ae3676 (patch) | |
tree | 60389f6ef604945e337ee890ccf10c493ab9e2a0 /blog/access-control | |
parent | daa0086eff780285f273cc4af527a091133eef72 (diff) | |
download | website-52a2cae0b3583d4148cbc183f6ce551f94ae3676.tar.gz |
create blog post about access control methods
Diffstat (limited to 'blog/access-control')
-rw-r--r-- | blog/access-control/weechat.cil | 171 | ||||
-rw-r--r-- | blog/access-control/xdgfile.cil | 47 |
2 files changed, 218 insertions, 0 deletions
diff --git a/blog/access-control/weechat.cil b/blog/access-control/weechat.cil new file mode 100644 index 0000000..c453063 --- /dev/null +++ b/blog/access-control/weechat.cil @@ -0,0 +1,171 @@ +;; Selinux is deny by default. So we must explicitly allow access to everything weechat needs, +;; including system libraries, the dynamic loader, xdg directories and more. + +;; reserve ports for irc purposes +(block irc + (portcon "tcp" 6667 port_context) + (portcon "tcp" 6697 port_context) + (blockinherit .net.port.unreserved.template)) + +;; define our weechat namespace +(block weechat + ;; most or all things have a template defined that we can use + ;; rarely do we write policy "from scratch", this includes subjects which are + ;; what we are creating here + (blockinherit .subj.template) + + ;; authorize sys.role to access the subj domain + (roletype .sys.role subj) + + ;; allow signaling ourself + (allow subj self (process (fork sigchld sigkill signal signull sigstop))) + + ;; allow setattr and getattr on our own files + (allow subj self (file (setattr getattr))) + + ;; allow reading and executing our own binary (/usr/bin/weechat) + ;; also allow a type transition from .sys.subj to .weechat.subj + (call .weechat.exec.subj_type_transition (.sys.subj subj)) + (call .weechat.exec.entrypoint_file_files (subj)) + (call .weechat.exec.mapexecute_file_files (subj)) + (call .weechat.exec.read_file_files (subj)) + + ;; nearly full access to our own data files + (call .weechat.data.search_file_dirs (subj)) + (call .weechat.data.create_file_dirs (subj)) + (call .weechat.data.create_file_files (subj)) + (call .weechat.data.delete_file_files (subj)) + (call .weechat.data.readwrite_file_files (subj)) + (call .weechat.data.rename_file_files (subj)) + (call .weechat.data.addname_file_dirs (subj)) + (call .weechat.data.deletename_file_dirs (subj)) + (call .weechat.data.rename_file_dirs (subj)) + + ;; same as above, nearly full access to our runtime files + (call .weechat.run.search_file_dirs (subj)) + (call .weechat.run.create_file_dirs (subj)) + (call .weechat.run.create_file_files (subj)) + (call .weechat.run.delete_file_files (subj)) + (call .weechat.run.readwrite_file_files (subj)) + (call .weechat.run.rename_file_files (subj)) + (call .weechat.run.addname_file_dirs (subj)) + (call .weechat.run.deletename_file_dirs (subj)) + (call .weechat.run.rename_file_dirs (subj)) + + ;; allow using unix sockets so long as they are the same type as ourself + (allow subj self (unix_dgram_socket (create sendto read write))) + + ;; allowing using the network but only irc ports specifically + (allow subj self create_tcp_socket) + (call irc.nameconnect_port_tcp_sockets (subj)) + + ;; You need to be able to traverse directories before you can access files. + ;; Each parent dir needs to be traversable, so we have to allow traversing root. + (call .root.search_file_dirs (subj)) + + ;; allow access to procfs + (call .proc.read_fs_lnk_files (subj)) + (call .proc.search_fs_dirs (subj)) + + ;; allow access to sysfs + (call .sys.search_fs_dirs (subj)) + (call .sys.read_fs_files (subj)) + + ;; use system libraries + (call .lib.search_file_dirs (subj)) + (call .lib.read_file_files (subj)) + (call .lib.mapexecute_file_files (subj)) + (call .lib.read_file_lnk_files (subj)) + + ;; read /etc + (call .conf.search_file_dirs (subj)) + (call .conf.read_file_files (subj)) + (call .conf.read_file_lnk_files (subj)) + ;; The dynamic loader is currently labeled .conf.file, and we need to be able to map and exec it. + ;; This is something you probably want to fix when writing your own policy on top of dssp5. + (call .conf.mapexecute_file_files (subj)) + + ;; use ssl certs + (call .cert.search_file_dirs (subj)) + (call .cert.read_file_files (subj)) + + ;; use terminal + (call .sys.use_subj_fds (subj)) + (call .dev.readwriteinherited_file_chr_files (subj)) + (call .ptytermdev.readwriteinherited_all_chr_files (subj)) + + ;; read /usr/share + (call .data.search_file_dirs (subj)) + (call .data.read_file_files (subj)) + + ;; traverse /home + (call .home.search_file_dirs (subj)) + + ;; allow creating dirs in ~/.config + (call .xdg.config.home.search_file_dirs (subj)) + (call .xdg.config.home.create_file_dirs (subj)) + (call .xdg.config.home.addname_file_dirs (subj)) + + ;; allow creating dirs in ~/.cache + (call .xdg.cache.home.search_file_dirs (subj)) + (call .xdg.cache.home.create_file_dirs (subj)) + (call .xdg.cache.home.addname_file_dirs (subj)) + + ;; allow creating dirs in ~/.local/share + (call .xdg.share.home.search_file_dirs (subj)) + (call .xdg.share.home.create_file_dirs (subj)) + (call .xdg.share.home.addname_file_dirs (subj)) + + ;; allow creating dirs in ~/.local/state + (call .xdg.state.home.search_file_dirs (subj)) + (call .xdg.state.home.create_file_dirs (subj)) + (call .xdg.state.home.addname_file_dirs (subj)) + + ;; allow creating files in the runtime directory + (call .run.search_file_dirs (subj)) + (call .run.create_file_dirs (subj)) + + (block exec + (blockinherit .file.exec.template) + + ;; Label the weechat executable itself. + ;; This along with some macros we called earlier cause executing weechat to transition to + ;; the weechat.subj context. + (filecon "/usr/bin/weechat" file file_context)) + + (block data + ;; This macro will be called at some point and is what makes the files and directories + ;; weechat creates in ~/.config and such transition to .weechat.data.file type from + ;; .home.file. + (macro xdg_file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .xdg.config.home.file_type_transition (ARG1 file ARG2 ARG3)) + (call .xdg.cache.home.file_type_transition (ARG1 file ARG2 ARG3)) + (call .xdg.share.home.file_type_transition (ARG1 file ARG2 ARG3)) + (call .xdg.state.home.file_type_transition (ARG1 file ARG2 ARG3))) + + (blockinherit .file.home.template) + + (filecon "HOME_DIR/\.config/weechat(/.*)?" any file_context) + (filecon "HOME_DIR/\.local/share/weechat(/.*)?" any file_context) + (filecon "HOME_DIR/\.local/state/weechat(/.*)?" any file_context) + (filecon "HOME_DIR/\.cache/weechat(/.*)?" any file_context)) + + (block run + ;; This is similar to the file type transition macro above, but for runtime files instead + ;; of config and state files. + (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .run.file_type_transition (ARG1 file ARG2 ARG3))) + + (blockinherit .file.run.template) + + (filecon "/run/user/%{USERID}/weechat" dir file_context) + (filecon "/run/user/%{USERID}/weechat/.*" any file_context))) + +;; we want files and dirs weechat creates to be of the weechat type so we call our +;; type transition macro. +(call .weechat.data.xdg_file_type_transition_file (.weechat.subj dir "*")) +(call .weechat.data.xdg_file_type_transition_file (.weechat.subj file "*")) + +;; same as above but for runtime files +(call .weechat.run.file_type_transition_file (.weechat.subj dir "weechat")) +(call .weechat.run.file_type_transition_file (.weechat.subj file "*")) diff --git a/blog/access-control/xdgfile.cil b/blog/access-control/xdgfile.cil new file mode 100644 index 0000000..67f5e31 --- /dev/null +++ b/blog/access-control/xdgfile.cil @@ -0,0 +1,47 @@ +;; create out xdg namespace +(block xdg + ;; we will create a subnamespace for each xdg file type (e.g config, cache, share, state) + (block config + ;; this next block isn't technically required but it shows that we are a subtype of .file.home + (block home + ;; create a macro to allow type transitions for files in our context + (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .home.file_type_transition_file (ARG1 file ARG2 ARG3))) + + ;; inherit the template which defines some types for us and also provides some macros + (blockinherit .file.home.template) + + ;; define a context for the ~/.cache directory itself + ;; hint: HOME_DIR is one of the few variables that can be interpolated into strings + (filecon "HOME_DIR/\.config" dir file_context) + (filecon "HOME_DIR/\.config/.*" file file_context))) + + (block cache + (block home + (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .home.file_type_transition_file (ARG1 file ARG2 ARG3))) + + (blockinherit .file.home.template) + + (filecon "HOME_DIR/\.cache" dir file_context) + (filecon "HOME_DIR/\.cache/.*" file file_context))) + + (block share + (block home + (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .home.file_type_transition_file (ARG1 file ARG2 ARG3))) + + (blockinherit .file.home.template) + + (filecon "HOME_DIR/\.local/share" dir file_context) + (filecon "HOME_DIR/\.local/share/.*" file file_context))) + + (block state + (block home + (macro file_type_transition_file ((type ARG1) (class ARG2) (name ARG3)) + (call .home.file_type_transition_file (ARG1 file ARG2 ARG3))) + + (blockinherit .file.home.template) + + (filecon "HOME_DIR/\.local/state" dir file_context) + (filecon "HOME_DIR/\.local/state/.*" file file_context)))) |