Limiting access to a file to only one or two known processes through SELinux

Hi,

I have a file and I want to limit access to it only to two processes. Others should be denied access.

I’ve tried sepolice generate --application /PATH/TO/EXE then added in app.te this file type:

type app_var_t;
files_type(app_var_t);
allow app_t app_var_t:file { unlink create open read write rename };

and run sudo ./app.sh to apply generated policy. Then I applied app_var_t type to file in question.

But I see two problems here:

  1. app_var_t is readable from unconfined processes. (accordingly because I’ve used files_type function)
  2. while app_t domain is applied to the application that should be able to read the file, when app started its process shows unconfined_t domain.

Any idea how can I create proper policy?

TIA

As you’ve noticed, SELinux won’t deny access to unconfined processes. Perhaps encryption is what you are looking for?

A simple way to encrypt a little data would be to use GPG. For example:

$ echo "encrypt me" | gpg --quiet --batch --passphrase 'p4ssw0rd' -o store.gpg -c -
$ ls -l store.gpg 
-rw-r--r--. 1 gregory gregory 81 Jul 26 11:55 store.gpg
$ xxd store.gpg 
00000000: 8c0d 0409 030a 23d1 8790 874d 8d66 ffd2  ......#....M.f..
00000010: 4001 b00e a49d 9d40 cf33 e7ee ac17 bbd7  @......@.3......
00000020: 3b96 92eb 6bbf f80f b464 6415 e2fb b868  ;...k....dd....h
00000030: 8da3 6619 6bc4 451a 1053 64b4 fa04 4e17  ..f.k.E..Sd...N.
00000040: fc89 310c 9248 39fa 54b5 d16c 89c9 8e7c  ..1..H9.T..l...|
00000050: b0
$ cat <(gpg --quiet --batch --passphrase 'p4ssw0rd' -d store.gpg)
encrypt me
$

Of course, then you have to ensure only your two processes have access to the password. :slightly_smiling_face:

Hey,

Yes, I know about the encryption but that wouldn’t protect against infostealers*. Meanwhile I think I’ve found the way to deny unconfined domains reading my specific files, but then there are other issues, such as a whitelisted app using ‘ls’ to read the directory, which in turn uses unconfined domain, not the app’s app_exec_t. I have to look into domain transitions I guess.

Edit:* think about protecting already encrypted files against physical access.

Yeah. I’d like to figure out confined users someday as well. Unfortunately, I don’t think it is ready for prime time yet.

What I would like to do is mark a filesystem (on a thumb drive that is normally not connected) as accessible only to processes running as a specific user account that I would not normally sign in with. (And when I do sign in with that special account, it would only be a console/virtual-terminal sign in.)

Good luck. :slightly_smiling_face:


Edit: A private NFSv4 server on a private LAN connection might be another option, but it would be a hassle to set up. When exported with sec=krb, NFSv4 will deny access to the filesystem (even the root user) unless the process has access to the right Kerberos ticket.

1 Like

You can try to use deny rules to limit unconfined_t - https://developers.redhat.com/articles/2025/06/04/how-selinux-deny-rules-improve-system-security e.g.

root@p16v:~# head -n 1 /etc/passwd 
root:x:0:0:Super User:/root:/bin/bash
root@p16v:~# cat deny-passwd.cil 
(deny unconfined_t passwd_file_t (file (execute execute_no_trans getattr ioctl lock map open read)))
root@p16v:~# semodule -i deny-passwd.cil
root@p16v:~# head -n 1 /etc/passwd 
head: cannot open '/etc/passwd' for reading: Permission denied

Then you could create your own domain and domain types which would be available only to your domain.

NOTE! that it would not protect files against unconfined root who can switch to permissive, or change the policy.

1 Like

Cool, thanks for the tip, I’ll try it.

To deny access through unconfined, you can either write a CIL policy with deny rules, which probably is the easiest way. But since unconfined_t can modify the Selinux policy, you need to protect against this through other means. Be aware that you might also need take care of other lax domains similar to unconfined_t. Or you create a new Selinux user which does not allow access to your type, but that’s definitely a lot more work.

Do you have a domain transition in place? The sepolicy generate command should create an interface app_run (or similar) which you could use. Could you show your policy here?