# Running software under SELinux-confined users to protect against exploits

**URL:** <https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505>\
**Category:** Rocky Linux Help & Support\
**Created:** [May 16, 2026, 2:40pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505 "2026-05-16T14:40:59Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 16, 2026, 2:40pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/1 "2026-05-16T14:40:59Z")

</div>

I’ve already tried starting a conversation about it on the Mattermost chat, perhaps this forum will be a better place. Is anyone else looking into SELinux-confined users to protect against the recent exploits and similar future exploits? I’ve tested on one server that Copy Fail, Dirty Frag, Fragnesia and ssh-keysign-pwn fail for users created with `useradd -Z user_u username` while they all succeed for normal users. I made the tests before updating the kernel or applying mitigations. I didn’t have to make any changes to SELinux configuration.

My plan for migrating the software I’m running from unconfined to confined users is to start with the most restrictive user type (`useradd -Z guest_u`), configure it with `setsebool` or `audit2allow` until the software runs normally, and if it becomes too much work, start again with a less restrictive user type (user\_u).

On the web I’ve only found one relevant article, tt’s about Copy Fail and SELinux, but it’s written from Debian perspective. I can’t link to it here because I don’t have the permission to post links. If anyone knows other resources or has any advice please let me know.

I’ll add some details from my tests in case someone finds them helpful.

Copy Fail exploit running as a confined user:

```plaintext
[testseuser1@instance-20260427-1814 copyfail]$ ./copy_fail_exp.py
Traceback (most recent call last):
  File "/home/testseuser1/2026.05.13.exploitcollection/copyfail/copyfail/./copy_fail_exp.py", line 24, in <module>
    while i<len(e):c(f,i,e[i:i+4]);i+=4
                   ^^^^^^^^^^^^^^^
  File "/home/testseuser1/2026.05.13.exploitcollection/copyfail/copyfail/./copy_fail_exp.py", line 11, in c
    u,_=a.accept()
        ^^^^^^^^^^
  File "/usr/lib64/python3.12/socket.py", line 295, in accept
    fd, addr = self._accept()
               ^^^^^^^^^^^^^^
PermissionError: [Errno 13] Permission denied

```

(I added some line breaks to the Python script to get better stack traces.)

SELinux denials:

```plaintext
time->Thu May 14 12:16:17 2026
type=PROCTITLE msg=audit(1778753777.096:10801): proctitle=707974686F6E33002E2F636F70795F6661696C5F6578702E7079
type=SYSCALL msg=audit(1778753777.096:10801): arch=c000003e syscall=288 success=no exit=-13 a0=4 a1=0 a2=0 a3=80000 items=0 ppid=8064 pid=8100 auid=1003 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=pts0 ses=19 comm="python3" exe="/usr/bin/python3.12" subj=user_u:user_r:user_t:s0 key=(null)
type=AVC msg=audit(1778753777.096:10801): avc: denied { accept } for pid=8100 comm="python3" scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=alg_socket permissive=0

```

Running as an unconfined user:

```plaintext
[user1@instance-20260427-1814 copyfail]$ ./copy_fail_exp.py
[root@instance-20260427-1814 copyfail]# 

```

Dirty Frag exploit running as a confined user:

```plaintext
[testseuser1@instance-20260427-1814 dirtyfrag]$ DIRTYFRAG_VERBOSE=1 ./exp
[su] SIOCSIFFLAGS: Operation not permitted
[su] corruption stage failed (status=0x100)

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1003 euid=1003 gid=1003
[!] socket(AF_RXRPC): Permission denied — module not loadable?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1003 euid=1003 gid=1003
[!] socket(AF_RXRPC): Permission denied — module not loadable?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1003 euid=1003 gid=1003
[!] socket(AF_RXRPC): Permission denied — module not loadable?

=== rxrpc/rxkad LPE EXPLOIT (uid=1000 → root) ===
[*] uid=1003 euid=1003 gid=1003
[!] socket(AF_RXRPC): Permission denied — module not loadable?
dirtyfrag: failed (rc=1)

```

SELinux denials:

```plaintext
time->Fri May 15 12:22:00 2026
type=PROCTITLE msg=audit(1778840520.956:36117): proctitle="./exp"
type=SYSCALL msg=audit(1778840520.956:36117): arch=c000003e syscall=16 success=no exit=-1 a0=3 a1=8914 a2=7ffe25b87110 a3=0 items=0 ppid=19550 pid=19551 auid=1003 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=pts0 ses=29 comm="exp" exe="/home/testseuser1/2026.05.13.exploitcollection/dirtyfrag/dirtyfrag/exp" subj=user_u:user_r:user_t:s0 key=(null)
type=AVC msg=audit(1778840520.956:36117): avc: denied { net_admin } for pid=19551 comm="exp" capability=12 scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=cap_userns permissive=0
----
time->Fri May 15 12:22:00 2026
type=PROCTITLE msg=audit(1778840520.956:36118): proctitle="./exp"
type=SYSCALL msg=audit(1778840520.956:36118): arch=c000003e syscall=41 success=no exit=-13 a0=21 a1=2 a2=2 a3=0 items=0 ppid=19281 pid=19550 auid=1003 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=pts0 ses=29 comm="exp" exe="/home/testseuser1/2026.05.13.exploitcollection/dirtyfrag/dirtyfrag/exp" subj=user_u:user_r:user_t:s0 key=(null)
type=AVC msg=audit(1778840520.956:36118): avc: denied { create } for pid=19550 comm="exp" scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=rxrpc_socket permissive=0

```

Running as an unconfined user:

```plaintext
[user1@instance-20260427-1814 dirtyfrag]$ ./exp
[root@instance-20260427-1814 dirtyfrag]# 

```

Fragnesia exploit running as a confined user:

```plaintext
[testseuser1@instance-20260427-1814 fragnesia]$ ./exp
[*] uid=1003 euid=1003 gid=1003 egid=1003
[*] mode=xfrm_espintcp_pagecache_replace collateral=after

[*] target=/usr/bin/su size=57344
outer_write_open_denied=1 errno=13 (Permission denied)
userns_setup: outer_uid=1003 outer_gid=1003 ns_uid=0 ns_gid=0
netns_setup=1
namespace_gate_failed: SIOCSIFFLAGS lo up errno=1 (Operation not permitted)

```

SELinux denials:

```plaintext
time->Fri May 15 13:42:19 2026
type=PROCTITLE msg=audit(1778845339.061:37455): proctitle="./exp"
type=SYSCALL msg=audit(1778845339.061:37455): arch=c000003e syscall=16 success=no exit=-1 a0=3 a1=8914 a2=7fffe1c29710 a3=0 items=0 ppid=20929 pid=20930 auid=1003 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=pts4 ses=42 comm="exp" exe="/home/testseuser1/2026.05.13.exploitcollection/fragnesia/fragnesia/exp" subj=user_u:user_r:user_t:s0 key=(null)
type=AVC msg=audit(1778845339.061:37455): avc: denied { net_admin } for pid=20930 comm="exp" capability=12 scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:user_t:s0 tclass=cap_userns permissive=0

```

Running as an unconfined user:

```plaintext
[user1@instance-20260427-1814 fragnesia]$ ./exp
[*] uid=1001 euid=1001 gid=1001 egid=1001
[*] mode=xfrm_espintcp_pagecache_replace collateral=after

[*] target=/usr/bin/su size=57344
outer_write_open_denied=1 errno=13 (Permission denied)
userns_setup: outer_uid=1001 outer_gid=1001 ns_uid=0 ns_gid=0
netns_setup=1
loopback_up=1
xfrm_espintcp_state_add=1
namespace_setup_complete=1
userns_root_mapped_to_outer_user_write_open_denied=1 errno=13 (Permission denied)

[*] timing: rx_pre_ulp=30000us tx_pre_splice=1000us rx_post_ulp=30000us
[*] range: offset=0x0 len=192 last=0xbf enc_len=4080 splice_len=4096
[*] union: transformed=0x0-0x10ae collateral_after=0xc0-0x10ae
[*] payload=7f454c4602010100000000000000000002003e0001000000780040000000000040000000000000000000000000000000000000004000380001000000000000000100000005000000000000000000000000004000000000000000400000000000b800000000000000b800000000000000001000000000000031ff31f631c0b06a0f05b0690f05b0740f056a00488d0512000000504889e2488d3d1200000031f66a3b580f055445524d3d787465726d002f62696e2f7368000000000000000000

stream0_table_entries=256

[*] smashing 192 bytes into read-only page cache changed=0 skipped=0 remaining=192
  0000 [7f]45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 
  0010 02 00 3e 00 01 00 00 00 78 00 40 00 00 00 00 00 
  0020 40 00 00 00 00 00 00 00 00 00 00 00 00 00[*] smashing 192 bytes into read-only page cache changed=176 skipped=16 remaining=000 00 00 00 00 0000 7f 45 4c 46 02 01 01 00 00 00 00 00 00 00 00 00 01 00 00 00 05 00 00 00 00 00 00 00 00 00 0010 02 00 3e 00 01 00 00 00 78 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 40 00 00 00 0020 40 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 b8 00 00 00 00 00 00 00 b8 00 00 00 00 00 0030 00 00 00 00 40 00 38 00 01 00 00 00 00 00 00 00 00 10 00 00 00 00 00 00 31 ff 31 f6 31 c0 0040 01 00 00 00 05 00 00 00 00 00 00 00 00 00 00 00 0f 05 b0 69 0f 05 b0 74 0f 05 6a 00 48 8d 0050 00 00 40 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 50 48 89 e2 48 8d 3d 12 00 00 00 0060 b8 00 00 00 00 00 00 00 b8 00 00 00 00 00
  00a0 6a 3b 58 0f 05 54 45 52 4d 3d 78 74 65 72[*] verifying 192 bytes...
[*] bytes_flip_summary len=192 changed=176 skipped=16 00 
[+] BUG: changed requested copied byte range to desired values (100%)
──────────────────────────────────────────────────
──────────

bash: /root/.bashrc: Permission denied
bash-5.2# 
exit
[user1@instance-20260427-1814 fragnesia]$ su
[root@instance-20260427-1814 fragnesia]# 

```

ssh-keysign-pwn chage\_pwn running as a confined user:

```plaintext
[testseuser1@instance-20260427-1814 ssh-keysign-pwn]$ ./chage_pwn
^C

```

(I manually stopped it after about 30 seconds.)

SELinux denials:

```plaintext
time->Fri May 15 15:14:25 2026
type=PROCTITLE msg=audit(1778850865.475:83176): proctitle="./chage_pwn"
type=SYSCALL msg=audit(1778850865.475:83176): arch=c000003e syscall=438 success=no exit=-1 a0=3 a1=1b a2=0 a3=0 items=0 ppid=21517 pid=21587 auid=1003 uid=1003 gid=1003 euid=1003 suid=1003 fsuid=1003 egid=1003 sgid=1003 fsgid=1003 tty=pts3 ses=50 comm="chage_pwn" exe="/home/testseuser1/2026.05.13.exploitcollection/ssh-keysign-pwn/ssh-keysign-pwn/chage_pwn" subj=user_u:user_r:user_t:s0 key=(null)
type=AVC msg=audit(1778850865.475:83176): avc: denied { ptrace } for pid=21587 comm="chage_pwn" scontext=user_u:user_r:user_t:s0 tcontext=user_u:user_r:passwd_t:s0 tclass=process permissive=0

```

Running as an unconfined user:

```plaintext
[user1@instance-20260427-1814 ssh-keysign-pwn]$ ./chage_pwn 
fd 6 -> /etc/shadow (round=1 try=163)
[here comes the content of /etc/shadow]

```

---

<div class="post-metadata">

**Author:** ![gerry666uk](https://avatars.discourse-cdn.com/v4/letter/g/dbc845/32.png) [@gerry666uk](https://forums.rockylinux.org/u/gerry666uk)\
**Post date:** [May 16, 2026, 5:48pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/2 "2026-05-16T17:48:27Z")

</div>

It would be good to know which exact capability is being denied, thereby stopping the exploit software from running?

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 16, 2026, 6:21pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/3 "2026-05-16T18:21:11Z")

</div>

You can find the denial entries in my first post. Here I’ll also show them in an easier-to-read format, produced by `audit2allow -M`

Copy Fail:

```plaintext

module module1 1.0;

require {
        type user_t;
        class alg_socket accept;
}

#============= user_t ==============
allow user_t self:alg_socket accept;

```

Dirty Frag and Fragnesia:

```plaintext

module module2 1.0;

require {
        type user_t;
        class rxrpc_socket create;
        class cap_userns net_admin;
}

#============= user_t ==============
allow user_t self:cap_userns net_admin;
allow user_t self:rxrpc_socket create;

```

ssh-keysign-pwn:

```plaintext

module module3 1.0;

require {
        type passwd_t;
        type user_t;
        class process ptrace;
}

#============= user_t ==============
allow user_t passwd_t:process ptrace;

```

These are the missing privileges, they are related to alg sockets, rxrpc sockets, user namespaces and ptrace. Users created with `useradd -Z user_u username` don’t have these privileges by default and I think the vast majority of applications don’t need them.

---

<div class="post-metadata">

**Author:** ![iwalker](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/iwalker/32/2599_2.png) [@iwalker](https://forums.rockylinux.org/u/iwalker)\
**Post date:** [May 17, 2026, 10:33am UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/4 "2026-05-17T10:33:41Z")

</div>

> [@PF92](#):
>
> On the web I’ve only found one relevant article, tt’s about Copy Fail and SELinux, but it’s written from Debian perspective. I can’t link to it here because I don’t have the permission to post links. If anyone knows other resources or has any advice please let me know.

New users can post links but mostly to allowed domains like rocky domains, once you pass the threshold after posting a little bit more, then you’ll be able to post more links. Unfortunate side-effect of spam users registering and posting spam links so we had to restrict it for new users with very little posts to their name. Once the trust level goes up you will be fine. Alternatively, we can add the domain to the allowed list to help make it easier - send us a message if needed.

I’m interested to know if when using `staff_u` or `sysadm_u` would the exploit occur. Mainly due to a lot of these using suid like sudo or su then those higher levels that do have access to sudo etc would no longer stop the exploiot from running. Saying that, since those users know they have higher privileges they are unlikely to use or try to use the exploit anyway. Worse, if their account has been compromised.

I think `user_u` is about the lowest you could go and probably the best place to start from the reading I did on the topic from some pages I found with google. It will take a lot of work though until things become more usable. I know I would have a lot of problems trying to use VPN’s, etc. The idea is interesting though if you don’t mind all the extra work to make it usable.

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 17, 2026, 6:07pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/5 "2026-05-17T18:07:17Z")

</div>

Thanks for your reply. It’s important to distinguish between user accounts meant for people and user accounts meant for individual applications. For user accounts meant for people, `user_u` could be too restrictive and `staff_u` or `sysadm_u` might be preferred. But when user accounts are meant for individual applications running on a server, `staff_u` and `sysadm_u` are probably too permissive for no good reason, even if they are still better than running unconfined.

In my tests today, `sysadm_u` only prevented Dirty Frag and Fragnesia, it didn’t prevent Copy Fail or ssh-keysign-pwn. `staff_u` prevented all 4 exploits just like `user_u`. However with `staff_u` it’s possible to start a shell with the same privileges as `sysadm_u` by running `newrole -r sysadm_r` and entering own account password. `user_u` is also better protected against potential security bugs in sudo. So I think in terms of security `staff_u` is about halfway between `user_u` and `sysadm_u`.

---

<div class="post-metadata">

**Author:** ![iwalker](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/iwalker/32/2599_2.png) [@iwalker](https://forums.rockylinux.org/u/iwalker)\
**Post date:** [May 19, 2026, 2:36pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/6 "2026-05-19T14:36:54Z")

</div>

I only did some quick tests yesterday, but sudo cannot be used by `user_u` anyway. You need at least `staff_u`. That said, I did have problems whereby I couldn’t read log files or use tools like `audit2allow` even with `sysadm_u`. I expect as the `root` user I could then get selinux to allow them so for everyday administrative stuff even with the higher levels a lot of extra selinux work is required before it even becomes usable.

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 19, 2026, 3:39pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/7 "2026-05-19T15:39:28Z")

</div>

> [@iwalker](#):
>
> I only did some quick tests yesterday, but sudo cannot be used by `user_u` anyway. You need at least `staff_u`.

That’s what I mean. Because `user_u` is blocked from using sudo, any security bugs in sudo shouldn’t affect `user_u`, but they might affect `staff_u`.

> [@iwalker](#):
>
> That said, I did have problems whereby I couldn’t read log files or use tools like `audit2allow` even with `sysadm_u`. I expect as the `root` user I could then get selinux to allow them so for everyday administrative stuff even with the higher levels a lot of extra selinux work is required before it even becomes usable.

Would it be possible to configure sudo or newrole so that your user is granted `unconfined_r` role after entering the password? If so, this might be the most realistic option for a confined account that can be used for administrative tasks.

---

<div class="post-metadata">

**Author:** ![iwalker](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/iwalker/32/2599_2.png) [@iwalker](https://forums.rockylinux.org/u/iwalker)\
**Post date:** [May 19, 2026, 4:06pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/8 "2026-05-19T16:06:58Z")

</div>

Actually just found out, giving the user `sysadm_u` would be the wrong thing anyway. The user would be given `staff_u`, but then in `/etc/sudoers.d/` configure a file with an equivalent below:

```auto
<example_user> ALL=(ALL) TYPE=sysadm_t ROLE=sysadm_r ALL

```

taken from here: [https://docs.redhat.com/en/documentation/red\_hat\_enterprise\_linux/8/html/using\_selinux/managing-confined-and-unconfined-users\_using-selinux#confining-an-administrator-using-sudo-and-the-sysadm\_r-role\_managing-confined-and-unconfined-users](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/8/html/using_selinux/managing-confined-and-unconfined-users_using-selinux#confining-an-administrator-using-sudo-and-the-sysadm_r-role_managing-confined-and-unconfined-users)

That I would expect probably solve the issues I was having. So we have to look at it at both user and role perspectives.

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 20, 2026, 10:15am UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/9 "2026-05-20T10:15:32Z")

</div>

`newrole` is easier to set up because it doesn’t require writing any configuration directives, just the `policycoreutils-newrole` package needs to be installed.

```plaintext
$ newrole -r unconfined_r
Password: 
$ su
Password: 
# id
uid=0(root) gid=0(root) groups=0(root) context=staff_u:unconfined_r:unconfined_t:s0-s0:c0.c1023

```

This gives an unconfined root shell in which any administrative tasks should be possible. It works because by default `unconfined_r` is one of the roles that `staff_u` can switch to:

```plaintext
# semanage user --list | grep staff_u
staff_u user s0 s0-s0:c0.c1023 system_r staff_r sysadm_r unconfined_r

```

sudo requires configuration but I guess it’s more flexible and can be more convenient if you want to use it often.

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 20, 2026, 7:54pm UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/10 "2026-05-20T19:54:01Z")

</div>

All of my applications are now running confined as `user_u` with no issues. I’ve only made these configuration changes:

```plaintext
setsebool -P selinuxuser_tcp_server on
setsebool -P selinuxuser_udp_server on

```

These settings apply to `user_u` and `staff_u` and they allow TCP and UDP servers on all ports (starting from 1024).

I had no luck with `guest_u` and `xguest_u`, there were multiple issues which I wasn’t able to solve.

Creating new confined users is easy with `useradd -Z user_u username`. Confining existing users is more complicated, this is what has worked for me:

1. Log in as the user. Stop the running applications and temporarily disable those crontab entries which could trigger during the process. Log out.

2. Log in as root.

3. Make sure no processes are running as the user:  
`# ps ufww -u username -U username`

4. Clear any existing SELinux mapping for the user:  
`# usermod -Z "" username`  
  
If you don’t clear an existing mapping, the next command can fail with strange errors such as: `[libsemanage]: MLS range s0-s0:c0.c1023 for Unix user (...) exceeds allowed range s0 for SELinux user user_u`  
  
Set up a new mapping:  
`# usermod -Z user_u username`  
  
`user_u` can be replaced with `staff_u`, `guest_u` or `xguest_u` if this is what you want.  
  
To list mappings:  
`# semanage login --list`  
  
If `semanage` is missing, the package to install is `policycoreutils-python-utils`.

5. Update SELinux attributes of files:  
`# restorecon -rF /home/username /var/spool/cron`  
  
If you have other locations where the user can write, you can add them too.

6. Log in as the user. Start the applications again. If you have disabled any crontab entries, reenable them.

7. As root, check for SELinux denials:  
`# ausearch -m avc -ts today`  
  
If there are denials, try to get more explanation:  
`# cat /var/log/audit/audit.log | audit2allow --why`

Useful resources:

- SELinux documentation from Red Hat: [https://docs.redhat.com/en/documentation/red\_hat\_enterprise\_linux/10/html/using\_selinux/index](https://docs.redhat.com/en/documentation/red_hat_enterprise_linux/10/html/using_selinux/index)
- SELinux documentation from Oracle: [https://docs.oracle.com/en/operating-systems/oracle-linux/selinux/](https://docs.oracle.com/en/operating-systems/oracle-linux/selinux/)
- SELinux chapter in Debian Handbook: [https://debian-handbook.info/browse/stable/sect.selinux.html](https://debian-handbook.info/browse/stable/sect.selinux.html)
- A blog article “Copy Fail on Debian and SE Linux”: [https://etbe.coker.com.au/2026/05/04/copy-fail-on-debian-and-se-linux/](https://etbe.coker.com.au/2026/05/04/copy-fail-on-debian-and-se-linux/)

---

<div class="post-metadata">

**Author:** ![iwalker](https://sea2.discourse-cdn.com/flex020/user_avatar/forums.rockylinux.org/iwalker/32/2599_2.png) [@iwalker](https://forums.rockylinux.org/u/iwalker)\
**Post date:** [May 21, 2026, 6:02am UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/11 "2026-05-21T06:02:09Z")

</div>

Great info 🙂

I didn’t use the usermod command to change for existing users, the command I used for changing between policies was:

```auto
semanage login -a -s user_u testuser

```

I did see the option on usermod previously when I started reading about this topic after your initial post, but then I found this website: [Confine untrusted users (including your children) with SELinux | Major Hayden](https://major.io/p/confine-untrusted-users-including-your-children-with-selinux/) which gave the command I used. Whether there is any difference or not, I’ve no idea. I used `restorecon` on the home directory for that user as well just in case.

---

<div class="post-metadata">

**Author:** ![PF92](https://avatars.discourse-cdn.com/v4/letter/p/3bc359/32.png) [@PF92](https://forums.rockylinux.org/u/PF92)\
**Post date:** [May 21, 2026, 10:52am UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/12 "2026-05-21T10:52:13Z")

</div>

I haven’t noticed any important differences between `usermod -Z` and the `semanage login` commands. In both cases `restorecon` is needed afterwards (you can check with `ls -lZ /home/username` that it’s not done automatically) and in both cases you need to clear an existing mapping first. For example, if you switch a user to `staff_u` with `semanage login -a -s staff_u username` and then try to switch the same user to `user_u` with `semanage login -a -s user_u username` (or `semanage login -m -s user_u username`), it will fail with the same error that I have written about, unless you first run `semanage login -d username`. I’ve chosen `usermod` because it’s easier to remember: `useradd -Z user_u username` creates a new user, `usermod -Z user_u username` modifies an existing user. `semanage` is always useful for listing existing mappings with `semanage login -l`.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex020/uploads/rockylinux/original/1X/91b7219eec10e30013422e4df76c1d898711a5d5.svg) [@system](https://forums.rockylinux.org/u/system)\
**Post date:** [July 20, 2026, 10:53am UTC](https://forums.rockylinux.org/t/running-software-under-selinux-confined-users-to-protect-against-exploits/20505/13 "2026-07-20T10:53:03Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
