Bug 2188714

Summary: SELinux prevents wg-quick@.service systemd unit from working
Product: [Fedora] Fedora Reporter: saturian1
Component: selinux-policyAssignee: Nikola Knazekova <nknazeko>
Status: ASSIGNED --- QA Contact: Fedora Extras Quality Assurance <extras-qa>
Severity: high Docs Contact:
Priority: medium    
Version: 42CC: darryl.lin+linux, dustymabe, dwalsh, equal.spot8348, haliu, joe, jwatt, lvrabec, mmalik, mszpak, nknazeko, omosnacek, pkoncity, vmojzis, zpytela
Target Milestone: ---Keywords: Regression, SELinux
Target Release: ---Flags: nknazeko: needinfo? (equal.spot8348)
mszpak: needinfo? (saturian1)
zpytela: needinfo? (equal.spot8348)
zpytela: needinfo? (saturian1)
Hardware: x86_64   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description saturian1 2023-04-21 20:19:38 UTC
In systemctl status wg-quick@... you can see:

internal:0:0-0: Error: Could not open file "/dev/fd/63": Permission denied

In `sudo ausearch -m AVC,USER_AVC,SELINUX_ERR,USER_SELINUX_ERR -ts recent` you can see:

type=AVC msg=audit(1682108035.623:1068): avc:  denied  { open } for  pid=184967 comm="nft" path="pipe:[391837]" dev="pipefs" ino=391837 scontext=system_u:system_r:iptables_t:s0 tcontext=system_u:system_r:wireguard_t:s0 tclass=fifo_file permissive=0

After using `setenforce 0` the unit works fine.

Reproducible: Always

Steps to Reproduce:
1. Have a wireguard config in /etc/wireguard/
2. Run systemctl start wg-quick@configname

Actual Results:  
Systemd unit fails

Expected Results:  
systemd unit works fine

Workaround iss to disable SELinux
In Fedora 37 it worked fine.

Comment 1 Joe Doss 2023-04-25 19:21:14 UTC
I am running F38 with SELinux and WireGuard just fine.  Is the SELinux context on your config file correct?

ls -laZ /etc/wireguard/yourconfig.conf

$ systemctl status wg-quick 
● wg-quick - WireGuard via wg-quick(8) for home
     Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled; preset: disabled)
    Drop-In: /usr/lib/systemd/system/service.d
             └─10-timeout-abort.conf
     Active: active (exited) since Thu 2023-04-20 11:39:29 CDT; 5 days ago
       Docs: man:wg-quick(8)
             man:wg(8)
             https://www.wireguard.com/
             https://www.wireguard.com/quickstart/
             https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
             https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
    Process: 12206 ExecStart=/usr/bin/wg-quick up home (code=exited, status=0/SUCCESS)
   Main PID: 12206 (code=exited, status=0/SUCCESS)
        CPU: 25ms

Apr 20 11:39:28 hostname systemd[1]: Starting wg-quick - WireGuard via wg-quick(8) for home...
Apr 20 11:39:28 hostname wg-quick[12206]: [#] ip link add home type wireguard
Apr 20 11:39:29 hostname wg-quick[12206]: [#] wg setconf home /dev/fd/63
Apr 20 11:39:29 hostname wg-quick[12206]: [#] ip -4 address add 192.168.22.2/24 dev home
Apr 20 11:39:29 hostname wg-quick[12206]: [#] ip link set mtu 1360 up dev home
Apr 20 11:39:29 hostname systemd[1]: Finished wg-quick - WireGuard via wg-quick(8) for home.
$ getenforce 
Enforcing
$ cat /etc/redhat-release 
Fedora release 38 (Thirty Eight)
$ sudo ls -laZ /etc/wireguard/home.conf
-rw-------. 1 root root unconfined_u:object_r:etc_t:s0 343 Dec 30  2021 /etc/wireguard/home.conf

Comment 2 saturian1 2023-04-26 10:41:14 UTC
(In reply to Joe Doss from comment #1)
> I am running F38 with SELinux and WireGuard just fine.  Is the SELinux
> context on your config file correct?
> 
> ls -laZ /etc/wireguard/yourconfig.conf
> 
> $ systemctl status wg-quick 
> ● wg-quick - WireGuard via wg-quick(8) for home
>      Loaded: loaded (/usr/lib/systemd/system/wg-quick@.service; enabled;
> preset: disabled)
>     Drop-In: /usr/lib/systemd/system/service.d
>              └─10-timeout-abort.conf
>      Active: active (exited) since Thu 2023-04-20 11:39:29 CDT; 5 days ago
>        Docs: man:wg-quick(8)
>              man:wg(8)
>              https://www.wireguard.com/
>              https://www.wireguard.com/quickstart/
>              https://git.zx2c4.com/wireguard-tools/about/src/man/wg-quick.8
>              https://git.zx2c4.com/wireguard-tools/about/src/man/wg.8
>     Process: 12206 ExecStart=/usr/bin/wg-quick up home (code=exited,
> status=0/SUCCESS)
>    Main PID: 12206 (code=exited, status=0/SUCCESS)
>         CPU: 25ms
> 
> Apr 20 11:39:28 hostname systemd[1]: Starting wg-quick -
> WireGuard via wg-quick(8) for home...
> Apr 20 11:39:28 hostname wg-quick[12206]: [#] ip link add home type wireguard
> Apr 20 11:39:29 hostname wg-quick[12206]: [#] wg setconf home /dev/fd/63
> Apr 20 11:39:29 hostname wg-quick[12206]: [#] ip -4 address add
> 192.168.22.2/24 dev home
> Apr 20 11:39:29 hostname wg-quick[12206]: [#] ip link set mtu 1360 up dev
> home
> Apr 20 11:39:29 hostname systemd[1]: Finished wg-quick -
> WireGuard via wg-quick(8) for home.
> $ getenforce 
> Enforcing
> $ cat /etc/redhat-release 
> Fedora release 38 (Thirty Eight)
> $ sudo ls -laZ /etc/wireguard/home.conf
> -rw-------. 1 root root unconfined_u:object_r:etc_t:s0 343 Dec 30  2021
> /etc/wireguard/home.conf

Yes, the contexts are like yours.
The /dev/fd/63 error is due to the file descriptor `<( ... )` used in `/usr/bin/wg-quick` shell script.
Here someone reported the same issue: https://github.com/fedora-silverblue/issue-tracker/issues/462

Comment 3 Joe Doss 2023-04-26 15:25:33 UTC
To clarify, you are running Fedora Silverblue 38 and seeing this issue?

Comment 4 saturian1 2023-04-27 13:17:06 UTC
No, I run Fedora Server 38, upgraded from 37


$ cat /etc/os-release 
NAME="Fedora Linux"
VERSION="38 (Thirty Eight)"
ID=fedora
VERSION_ID=38
VERSION_CODENAME=""
PLATFORM_ID="platform:f38"
PRETTY_NAME="Fedora Linux 38 (Thirty Eight)"
ANSI_COLOR="0;38;2;60;110;180"
LOGO=fedora-logo-icon
CPE_NAME="cpe:/o:fedoraproject:fedora:38"
DEFAULT_HOSTNAME="fedora"
HOME_URL="https://fedoraproject.org/"
DOCUMENTATION_URL="https://docs.fedoraproject.org/en-US/fedora/f38/system-administrators-guide/"
SUPPORT_URL="https://ask.fedoraproject.org/"
BUG_REPORT_URL="https://bugzilla.redhat.com/"
REDHAT_BUGZILLA_PRODUCT="Fedora"
REDHAT_BUGZILLA_PRODUCT_VERSION=38
REDHAT_SUPPORT_PRODUCT="Fedora"
REDHAT_SUPPORT_PRODUCT_VERSION=38
SUPPORT_END=2024-05-14

Comment 5 Joe Doss 2023-04-27 13:55:45 UTC
This sounds like a bug within selinux-policy, not the wireguard-tools package itself. I am not seeing the issue on Fedora 38 and I upgraded from 37 as well. What version of selinux-policy do you have? I assume it is the same as me:

$ rpm -qa |grep selinux-policy
selinux-policy-38.10-1.fc38.noarch
selinux-policy-targeted-38.10-1.fc38.noarch

Comment 6 quentin9696 2023-05-05 02:22:20 UTC
I add more details here: 
https://github.com/fedora-selinux/selinux-policy/issues/1675

Since Fedora38, Wireguard is now isolated to it's own context. The fact is that wg-quick allow us to use command within PreDown/PostDown and PostUp/PreUp directive (like created some iptables rules, setup the private key only at runtime using systemd-creds, setup some route using ip route). Those directive are be blocked by selinux isolation. 

I think the best way is to keep the default policy, but also creates some optional that can be activated by bool. 

What do you think?

Comment 7 Dusty Mabe 2023-05-05 20:10:29 UTC
Moving this to selinux-policy since I think that's where the policy for this is shipped anyway.

Comment 8 Dusty Mabe 2023-05-10 03:43:48 UTC
Maybe since the plugins/hooks can run any code they want we should just enable them to run unconfined via an SELinux boolean?

Comment 9 Nikola Knazekova 2023-07-13 07:13:13 UTC
Hi,
can you please reproduce the issue in the permissive mode? 
Please do:
# setenforce 0

Thank you

Comment 10 quentin9696 2023-07-14 18:53:23 UTC
Hi Nikola, 

Here are logs https://gist.github.com/quentin9696/47547a8a163d3b62cb69db053a4f83ce

To reproduce: 
1. mkdir -p /run/credstore.encrypted/
2. wg genkey | systemd-creds encrypt -H - /run/credstore.encrypted/private-key
3. Create a file `/etc/wireguard/wg0.conf` with the content
[Interface]
Address    = 10.0.0.1/32
ListenPort = 52445
MTU        = 1420

PostUp     = wg set %i private-key <(/usr/bin/systemd-creds decrypt /run/credstore.encrypted/private-key)
PostUp     = iptables-restore --noflush /etc/wireguard/%i.iptables
PostDown   = iptables-restore --noflush /etc/wireguard/%i_deletion.iptables

[Peer]
PublicKey = qKHX0r90nYIwctRi2dk9P5rTZI561PgulSG6s87H5W0=
AllowedIPs = 10.0.0.2/32
4. Create a file `/etc/wireguard/wg0.iptables` with the content
*mangle
:wg0_FILTER - [0:0]
-I wg0_FILTER -j DROP
COMMIT
*mangle
-I wg0_FILTER -d 192.168.0.0/16 -j ACCEPT
COMMIT
*nat
-I POSTROUTING -o ens5 -j MASQUERADE
COMMIT
*mangle
-I PREROUTING -i wg0 -j wg0_FILTER
COMMIT
5. Create a file `/etc/wireguard/wg0_deletion.iptables` with the content
*mangle
:wg0_FILTER - [0:0]
-D wg0_FILTER -j DROP
COMMIT
*mangle
-D wg0_FILTER -d 192.168.0.0/16 -j ACCEPT
COMMIT
*nat
-D POSTROUTING -o ens5 -j MASQUERADE
COMMIT
*mangle
-D PREROUTING -i wg0 -j wg0_FILTER
COMMIT
6. Run `systemctl start wg-quick@wg0`


I want to add something. Since it's a common use case to makes some network actions after starting WireGuard,I think the policy should include some boolean to enable the most common actions, like running some iptables commands, network actions (add route, enable IP forwarding, create a NAT), fetch a secret (from systemd-creds or Hashicorp Vault), etc...
If we consider one action too specific, we can still create a boolean to unconfined the wireguard process or create a specific boolean for that. 

What do you think?

Comment 11 Dusty Mabe 2023-08-08 21:10:09 UTC
Hey Nikola. Any updates on this one?

Comment 12 Nikola Knazekova 2023-08-12 16:47:33 UTC
Hi,

sorry for late response. 

Can you reproduce the issue again with full auditing enabled?

1) Open the /etc/audit/rules.d/audit.rules file in an editor.
2) Remove the following line if it exists:
-a task,never
3) Add the following line to the end of the file:
-w /etc/shadow -p w
4) Restart the audit daemon:
  # service auditd restart
5) Re-run your scenario.
6) Collect AVC denials:
  # ausearch -i -m avc,user_avc,selinux_err,user_selinux_err -ts today

Comment 13 Marcin Zajaczkowski 2024-02-17 22:25:39 UTC
A related issue (but with firewalld): https://bugzilla.redhat.com/show_bug.cgi?id=2255572

> Workaround iss to disable SELinux

@saturian1 You might want to use the technique described in bug 2255572 to create a custom policy to allow wireguard to call iptables.


Btw, some people also suggest using NetworkManager to configure Wireguard on a server, so maybe it would be possible/easier in your case (I haven't checked): https://github.com/coreos/fedora-coreos-tracker/issues/1487#issuecomment-1752103218

Comment 14 Zdenek Pytela 2024-02-21 12:33:22 UTC
(In reply to quentin9696 from comment #10)
> Here are logs
> https://gist.github.com/quentin9696/47547a8a163d3b62cb69db053a4f83ce
Unfortunately, these logs are of little use as they are trimmed. I can see dealing with /etc/pki/tls/openssl.cnf,
generated private key and /var/lib/systemd/credential.secret, but not all details. I understand though some policy adjustments are needed.

> I want to add something. Since it's a common use case to makes some network
> actions after starting WireGuard,I think the policy should include some
> boolean to enable the most common actions, like running some iptables
> commands, network actions (add route, enable IP forwarding, create a NAT),
> fetch a secret (from systemd-creds or Hashicorp Vault), etc...
> If we consider one action too specific, we can still create a boolean to
> unconfined the wireguard process or create a specific boolean for that. 
If it really is a common use case, the policy can allow them even without a boolean.
We need to have first some use cases described for policy to update and for automated tests, we'd appreciate any help with this.

Comment 15 Zdenek Pytela 2024-02-21 12:42:37 UTC
(In reply to Marcin Zajaczkowski from comment #13)
> A related issue (but with firewalld):
> https://bugzilla.redhat.com/show_bug.cgi?id=2255572
> 
> > Workaround iss to disable SELinux
> 
> @saturian1 You might want to use the technique described in bug
> 2255572 to create a custom policy to allow wireguard to call iptables.
Which technique do you mean?
We anyway have a domain transition in policy since 2 years ago.

> Btw, some people also suggest using NetworkManager to configure Wireguard on
> a server, so maybe it would be possible/easier in your case (I haven't
> checked):
> https://github.com/coreos/fedora-coreos-tracker/issues/1487#issuecomment-
> 1752103218
I suppose this would also require a domain transition rule which is not present.

Comment 16 Zdenek Pytela 2024-02-21 12:45:51 UTC
I cannot find any recommended path for storing keys or other transient data.
I suppose it could be /run/wireguard or somewhere in /var, can you help me?

If there was a clearly stated path (documentation and/or the service unit file), we could define a transition and allow the needed rules for wireguard.

Comment 17 Hangbin Liu 2024-02-22 03:02:12 UTC
(In reply to Zdenek Pytela from comment #16)
> I cannot find any recommended path for storing keys or other transient data.
> I suppose it could be /run/wireguard or somewhere in /var, can you help me?
> 
> If there was a clearly stated path (documentation and/or the service unit
> file), we could define a transition and allow the needed rules for wireguard.

From the wireguard README, it recommended:

`RUNSTATEDIR`          default: `/var/run`

https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/wireguard-tools.git/tree/README.md#n31

Comment 18 Zdenek Pytela 2024-02-22 10:07:21 UTC
(In reply to Hangbin Liu from comment #17)
> (In reply to Zdenek Pytela from comment #16)
> > I cannot find any recommended path for storing keys or other transient data.
> > I suppose it could be /run/wireguard or somewhere in /var, can you help me?
> > 
> > If there was a clearly stated path (documentation and/or the service unit
> > file), we could define a transition and allow the needed rules for wireguard.
> 
> From the wireguard README, it recommended:
> 
> `RUNSTATEDIR`          default: `/var/run`
> 
> https://git.kernel.org/pub/scm/linux/kernel/git/zx2c4/wireguard-tools.git/
> tree/README.md#n31

OK, thank you, I can set up policy for /run/wireguard, but it would be good if there was some expected directory or file name, there does not seem to be any.

Comment 19 Aoife Moloney 2024-05-07 16:09:06 UTC
This message is a reminder that Fedora Linux 38 is nearing its end of life.
Fedora will stop maintaining and issuing updates for Fedora Linux 38 on 2024-05-21.
It is Fedora's policy to close all bug reports from releases that are no longer
maintained. At that time this bug will be closed as EOL if it remains open with a
'version' of '38'.

Package Maintainer: If you wish for this bug to remain open because you
plan to fix it in a currently maintained version, change the 'version' 
to a later Fedora Linux version. Note that the version field may be hidden.
Click the "Show advanced fields" button if you do not see it.

Thank you for reporting this issue and we are sorry that we were not 
able to fix it before Fedora Linux 38 is end of life. If you would still like 
to see this bug fixed and are able to reproduce it against a later version 
of Fedora Linux, you are encouraged to change the 'version' to a later version
prior to this bug being closed.

Comment 20 Aoife Moloney 2025-02-26 12:53:35 UTC
This bug appears to have been reported against 'rawhide' during the Fedora Linux 42 development cycle.
Changing version to 42.