Tinc vs. Systemd Hardening: Could not open /dev/net/tun: No such file or directory
Hi, after I updated this morning my tinc vpn setup stopped working. Journal: ... Jan 12 15:19:15 muckefuck tincd[23111]: tincd 1.0.36 starting, debug level 0 Jan 12 15:19:15 muckefuck tincd[23111]: Could not open /dev/net/tun: No such file or directory Jan 12 15:19:15 muckefuck tincd[23111]: Terminating ... After poking around a bit I found that the tinc.service file sets PrivateDevices=true as part of the Systemd hardening effort (bsc#1181400) If I set it to false tinc can access /dev/net/tun. Why is this failing only now? The tinc Package was last changed a year ago. Is it safe to set PrivateDevices=false or is there another way? cheers Wonko
On Thu, Jan 12, 2023 at 03:28:00PM +0100, Wonko Pfux wrote:
Hi,
after I updated this morning my tinc vpn setup stopped working.
Journal: ... Jan 12 15:19:15 muckefuck tincd[23111]: tincd 1.0.36 starting, debug level 0 Jan 12 15:19:15 muckefuck tincd[23111]: Could not open /dev/net/tun: No such file or directory Jan 12 15:19:15 muckefuck tincd[23111]: Terminating ...
After poking around a bit I found that the tinc.service file sets PrivateDevices=true as part of the Systemd hardening effort (bsc#1181400)
If I set it to false tinc can access /dev/net/tun. Why is this failing only now? The tinc Package was last changed a year ago.
No it was not. Just after sending I figured that the "Changed" column in OBS does not reflect accepted requsts. https://build.opensuse.org/request/show/1056357 was in fact changed 6 Days ago. And is the culprit.
Is it safe to set PrivateDevices=false or is there another way?
cheers Wonko
On Thu, Jan 12, 2023 at 05:43:51PM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 5:28 PM Wonko Pfux <42@wonko.de> wrote:
Is it safe to set PrivateDevices=false
It is just as safe as it was before this change was introduced.
or is there another way?
You may try to add
DeviceAllow=/dev/net/tun
It seems PrivateDevices=true overrides DeviceAllow=/dev/net/tun. So both are nessesary?: PrivateDevices=false DeviceAllow=/dev/net/tun The systemd Documentation does not state that DeviceAllow means all others are disallowed but: "When access to all physical devices should be disallowed, PrivateDevices= may be used instead" In the doc for DevicePolicy, which is not set in the service file, it is said that the default (auto) "allows access to all devices if no explicit DeviceAllow= is present" I have not found docs how ProtectSystem, which is set to full , affects DevicePolicy. cu Wonko
On 12.01.2023 18:34, Wonko Pfux wrote:
On Thu, Jan 12, 2023 at 05:43:51PM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 5:28 PM Wonko Pfux <42@wonko.de> wrote:
Is it safe to set PrivateDevices=false
It is just as safe as it was before this change was introduced.
or is there another way?
You may try to add
DeviceAllow=/dev/net/tun
It seems PrivateDevices=true overrides DeviceAllow=/dev/net/tun.
Have you tried it?
So both are nessesary?: PrivateDevices=false DeviceAllow=/dev/net/tun
The systemd Documentation does not state that DeviceAllow means all others are disallowed but: "When access to all physical devices should be disallowed, PrivateDevices= may be used instead"
In the doc for DevicePolicy, which is not set in the service file, it is said that the default (auto) "allows access to all devices if no explicit DeviceAllow= is present"
I have not found docs how ProtectSystem, which is set to full , affects DevicePolicy.
cu Wonko
On Thu, Jan 12, 2023 at 07:55:07PM +0300, Andrei Borzenkov wrote:
On 12.01.2023 18:34, Wonko Pfux wrote:
On Thu, Jan 12, 2023 at 05:43:51PM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 5:28 PM Wonko Pfux <42@wonko.de> wrote:
Is it safe to set PrivateDevices=false
It is just as safe as it was before this change was introduced.
or is there another way?
You may try to add
DeviceAllow=/dev/net/tun
It seems PrivateDevices=true overrides DeviceAllow=/dev/net/tun.
Have you tried it?
yes Unfortunately it seems my assumtion was wrong: /proc is fully visible to the process. Just as if there was no DeviceAllow=
So both are nessesary?: PrivateDevices=false DeviceAllow=/dev/net/tun
The systemd Documentation does not state that DeviceAllow means all others are disallowed but: "When access to all physical devices should be disallowed, PrivateDevices= may be used instead"
In the doc for DevicePolicy, which is not set in the service file, it is said that the default (auto) "allows access to all devices if no explicit DeviceAllow= is present"
I have not found docs how ProtectSystem, which is set to full , affects DevicePolicy.
cu Wonko
On Thu, Jan 12, 2023 at 9:30 PM Wonko Pfux <42@wonko.de> wrote:
On Thu, Jan 12, 2023 at 07:55:07PM +0300, Andrei Borzenkov wrote:
On 12.01.2023 18:34, Wonko Pfux wrote:
On Thu, Jan 12, 2023 at 05:43:51PM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 5:28 PM Wonko Pfux <42@wonko.de> wrote:
Is it safe to set PrivateDevices=false
It is just as safe as it was before this change was introduced.
or is there another way?
You may try to add
DeviceAllow=/dev/net/tun
It seems PrivateDevices=true overrides DeviceAllow=/dev/net/tun.
Have you tried it?
yes
Unfortunately it seems my assumtion was wrong: /proc is fully visible to the process. Just as if there was no DeviceAllow=
I am not sure how /proc is related here, but yes, it seems that there is no way to create additional device nodes with PrivateDevices - you only get several "standard" ones. So you should open a bug report to remove PrivateDevices. As far as I can tell, DevicePolicy=closed should provide a similar level of protection as PrivateDevices but using an eBPF filter to deny access to visible device nodes. So you may consider DevicePolicy=closed DeviceAllow=/dev/net/tun
So both are nessesary?: PrivateDevices=false
It is necessary as a temporary workaround until package is fixed, yes.
DeviceAllow=/dev/net/tun
No, if you disable PrivateDevices it is not necessary (unless you add some other hardening directives like DevicePolicy)
The systemd Documentation does not state that DeviceAllow means all others are disallowed but: "When access to all physical devices should be disallowed, PrivateDevices= may be used instead"
In the doc for DevicePolicy, which is not set in the service file, it is said that the default (auto) "allows access to all devices if no explicit DeviceAllow= is present"
I have not found docs how ProtectSystem, which is set to full , affects DevicePolicy.
It should not.
On Fri, Jan 13, 2023 at 09:42:14AM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 9:30 PM Wonko Pfux <42@wonko.de> wrote:
On Thu, Jan 12, 2023 at 07:55:07PM +0300, Andrei Borzenkov wrote:
On 12.01.2023 18:34, Wonko Pfux wrote:
On Thu, Jan 12, 2023 at 05:43:51PM +0300, Andrei Borzenkov wrote:
On Thu, Jan 12, 2023 at 5:28 PM Wonko Pfux <42@wonko.de> wrote:
Is it safe to set PrivateDevices=false
It is just as safe as it was before this change was introduced.
or is there another way?
You may try to add
DeviceAllow=/dev/net/tun
It seems PrivateDevices=true overrides DeviceAllow=/dev/net/tun.
Have you tried it?
yes
Unfortunately it seems my assumtion was wrong: /proc is fully visible to the process. Just as if there was no DeviceAllow=
I am not sure how /proc is related here, but yes, it seems that there is no way to create additional device nodes with PrivateDevices - you only get several "standard" ones. So you should open a bug report to remove PrivateDevices.
/proc is not related that was a Brainfart on my side. Sorry for the discraction. I have commented in bsc#1181400 the report that is referenced in the change that broke tinc. I have also created https://build.opensuse.org/request/show/1058030 To get tinc working again. BUT While trying to figure out what a secure config should be I stumbled across DevicePolicy not doing what is described in the systemd docs.
As far as I can tell, DevicePolicy=closed should provide a similar level of protection as PrivateDevices but using an eBPF filter to deny access to visible device nodes. So you may consider
DevicePolicy=closed
The systemd docs state DevicePolicy=closed gives you: "access to standard pseudo devices including /dev/null, /dev/zero, /dev/full, /dev/random, and /dev/urandom."
DeviceAllow=/dev/net/tun
That is only mentioned in combination with DevicePolicy=auto: "allows access to all devices if no explicit DeviceAllow= is present. This is the default. " I went through a couble of permutations to test this: Replaced ExecStart to be able to see what is visible in /dev ExecStart=bash -c 'find /dev -maxdepth 1 -printf " %%P" ;/usr/sbin/tincd -n %i -D' With the current Package this show that /dev contains: stderr stdout stdin fd core tty urandom random full zero null log hugepages mqueue shm char ptmx pts No net/tun i-PrivateDevices=true +DeviceAllow=/dev/net/tun /dev fully populated inc /dev/net/tun ------ -PrivateDevices=true +DevicePolicy=closed /dev fully populated inc /dev/net/tun ------ -PrivateDevices=true +DevicePolicy=closed +DeviceAllow=/dev/net/tun /dev fully populated inc /dev/net/tun ------ -PrivateDevices=true +DevicePolicy=auto +DeviceAllow=/dev/net/tun /dev fully populated inc /dev/net/tun ------ -PrivateDevices=true +DevicePolicy=strict Failed to set up standard input: Operation not permitted
So both are nessesary?: PrivateDevices=false
It is necessary as a temporary workaround until package is fixed, yes.
DeviceAllow=/dev/net/tun
No, if you disable PrivateDevices it is not necessary (unless you add some other hardening directives like DevicePolicy)
The systemd Documentation does not state that DeviceAllow means all others are disallowed but: "When access to all physical devices should be disallowed, PrivateDevices= may be used instead"
In the doc for DevicePolicy, which is not set in the service file, it is said that the default (auto) "allows access to all devices if no explicit DeviceAllow= is present"
I have not found docs how ProtectSystem, which is set to full , affects DevicePolicy.
It should not.
On Fri, Jan 13, 2023 at 1:26 PM Wonko Pfux <42@wonko.de> wrote: ...
I have commented in bsc#1181400 the report that is referenced in the
Each package has different requirements, so each package really needs its own post-hardening bug report.
change that broke tinc. I have also created https://build.opensuse.org/request/show/1058030
Personally I prefer explicit DevicePolicy=closed for documentation purposes.
To get tinc working again.
BUT
While trying to figure out what a secure config should be I stumbled across DevicePolicy not doing what is described in the systemd docs.
As far as I can tell, DevicePolicy=closed should provide a similar level of protection as PrivateDevices but using an eBPF filter to deny access to visible device nodes. So you may consider
DevicePolicy=closed
The systemd docs state DevicePolicy=closed gives you: "access to standard pseudo devices including /dev/null, /dev/zero, /dev/full, /dev/random, and /dev/urandom."
DeviceAllow=/dev/net/tun
That is only mentioned in combination with DevicePolicy=auto: "allows access to all devices if no explicit DeviceAllow= is present. This is the default. "
What it tries to say is that if there is at least one DeviceAllow, only these devices are accessible. What it forgets to mention, that it *also* makes standard devices accessible. I.e. it is equivalent (really, just look at source code) to DevicePolicy=closed DeviceAllow=/dev/net/tun which is far better by making it obvious.
I went through a couble of permutations to test this:
Replaced ExecStart to be able to see what is visible in /dev
ExecStart=bash -c 'find /dev -maxdepth 1 -printf " %%P" ;/usr/sbin/tincd -n %i -D'
I am not sure what the point is. DevicePolicy does not hide device nodes, it restricts access to them. So whatever policy you use, you will see exactly the same /dev content. PrivateDevices is really a big hammer to completely hide /dev content.
With the current Package this show that /dev contains: stderr stdout stdin fd core tty urandom random full zero null log hugepages mqueue shm char ptmx pts No net/tun
i-PrivateDevices=true +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=closed
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=closed +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=auto +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=strict
Failed to set up standard input: Operation not permitted
Of course. DevicePolicy=strict means that only devices explicitly allowed by DeviceAllow are accessible. The /dev content still remains the same.
Sory was AFK for a few days. On Fri, Jan 13, 2023 at 02:05:52PM +0300, Andrei Borzenkov wrote:
On Fri, Jan 13, 2023 at 1:26 PM Wonko Pfux <42@wonko.de> wrote: ...
I have commented in bsc#1181400 the report that is referenced in the
Each package has different requirements, so each package really needs its own post-hardening bug report.
change that broke tinc. I have also created https://build.opensuse.org/request/show/1058030
Personally I prefer explicit DevicePolicy=closed for documentation purposes.
To get tinc working again.
BUT
While trying to figure out what a secure config should be I stumbled across DevicePolicy not doing what is described in the systemd docs.
As far as I can tell, DevicePolicy=closed should provide a similar level of protection as PrivateDevices but using an eBPF filter to deny access to visible device nodes. So you may consider
DevicePolicy=closed
The systemd docs state DevicePolicy=closed gives you: "access to standard pseudo devices including /dev/null, /dev/zero, /dev/full, /dev/random, and /dev/urandom."
DeviceAllow=/dev/net/tun
That is only mentioned in combination with DevicePolicy=auto: "allows access to all devices if no explicit DeviceAllow= is present. This is the default. "
What it tries to say is that if there is at least one DeviceAllow, only these devices are accessible. What it forgets to mention, that it *also* makes standard devices accessible. I.e. it is equivalent (really, just look at source code) to
DevicePolicy=closed DeviceAllow=/dev/net/tun
I will implement this.
which is far better by making it obvious.
I went through a couble of permutations to test this:
Replaced ExecStart to be able to see what is visible in /dev
ExecStart=bash -c 'find /dev -maxdepth 1 -printf " %%P" ;/usr/sbin/tincd -n %i -D'
I am not sure what the point is. DevicePolicy does not hide device nodes, it restricts access to them. So whatever policy you use, you will see exactly the same /dev content. PrivateDevices is really a big hammer to completely hide /dev content.
That is where I was confused: I thought that /dev would be empty but for the defined files. I failed to understand that its done through eBPF. I am getting old...
With the current Package this show that /dev contains: stderr stdout stdin fd core tty urandom random full zero null log hugepages mqueue shm char ptmx pts No net/tun
i-PrivateDevices=true +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=closed
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=closed +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=auto +DeviceAllow=/dev/net/tun
/dev fully populated inc /dev/net/tun
------
-PrivateDevices=true +DevicePolicy=strict
Failed to set up standard input: Operation not permitted
Of course. DevicePolicy=strict means that only devices explicitly allowed by DeviceAllow are accessible. The /dev content still remains the same.
participants (2)
-
Andrei Borzenkov
-
Wonko Pfux